Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
tcp
TCP_NODELAY_Nagle算法_粘包
TCP客户端断开重练问题
发布于 2013-12-18 10:31:44 浏览:6036
订阅该版
最近小菜菜我又要做RTT连接远程服务器的项目,也是最近搞的一头雾水,情况是这样的: 我用RTT创建俩线程一个是TCP连接线程优先级是13,一个是TCP心跳包的线程优先级是14, 1.TCP连接线程优先级高先运行,先分配一块内存作为TCP数据接收,然后建socket,然后对远端IP连接,连接之后先发送一串数据,紧接着挂起到LWIP_RECV上,等待服务器数据,无数据此线程挂起, 2.TCP心跳包线程开始运行,他主动用上一个线程建立的SOCKRT发送一个心跳包LWIP——send();然后他就延时挂起了时间是10秒,也就是说这个线程是每十秒运行一次发送心跳包, 3.网络连接成正常数据都正常,但是实际并不是这样的要考虑断网或者服务器异常的情况,那么我就模拟服务器异常,我希望只要服务器一上线我RTT既可以连接上,所以我在远程服务器用了网络调试助手,我只要点击监听/断开就好了,就可以模拟出来,OK下面说现象。 当远程服务器断开之后,那么优先级为13的TCP链接线程挂起在邮箱上就会返回错误,这时先销毁socket,然后再重复创建链接,如果不成功一直重复创建链接销毁的过程,如果成功就发送一串数据,继续挂起在RECV上等待,实际情况是这样的,他会从新连接,会执行,但是。。。。。 但是当服务器端监听/断开很频繁的时候最多可以自动重连4次-6次不等,就进入TCP/IP的断言里面 ```c void sys_arch_assert(const char* file, int line) ``` 这个函数, 如果服务器端监听/断开不频繁,控制在10秒以外,就可以一直的有重练接,不会进入断言, 也就是说又一个未知的时间内做了一些什么事情,让他进入了断言, 我初步考虑是TCP/IP和APP程序之间的优先级问题,或者是NET_TX,NET_RX线程优先级问题, 目前我的TCPIP处理线程优先级是12,TXRX是优先级是15.TCP 连接线程优先级是13,心跳线程是14, 如果调整为TCPIP处理线程优先级是10,TXRX是优先级是11.TCP 连接线程优先级是13,心跳线程是14,也就是说抬高TCP/IP的优先级,会不会好呢?我想这个应该大问题没有,那个细节忽略了, 这是TCP连接线程的代码: ```c void tcpclient_SC(const char *url, int port) { while(1) { char *recv_data; struct hostent *host; rt_uint32_t bytes_received; struct sockaddr_in server_addr; recv_data = rt_malloc(BUF); if (recv_data == RT_NULL) { rt_kprintf("No memory "); return; } start: // rt_thread_delay(300); //rt_thread_delay(1000); /* 通过函数入口参数url 获得host 地址(如果是域名,会做域名解析) */ // host = gethostbyname(url); /* 分配用于存放接收数据的缓冲 */ /* 创建一个socket,类型是SOCKET_STREAM,TCP 类型 */ if ((tcp_clint_sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) { /* 创建socket 失败 */ rt_kprintf("Socket error "); /* 释放接收缓冲 */ rt_free(recv_data); return; } /* 初始化预连接的服务端地址 */ server_addr.sin_family = AF_INET; server_addr.sin_port = htons(port); server_addr.sin_addr = *((struct in_addr *)host->h_addr); rt_memset(&(server_addr.sin_zero), 0,sizeof(server_addr.sin_zero)); /* 连接到服务端 */ if (connect(tcp_clint_sock, (struct sockaddr *)&server_addr,sizeof(struct sockaddr)) == -1) { /* 连接失败 */ rt_kprintf("Connect error "); lwip_close(tcp_clint_sock ); /*释放接收缓冲 */ // rt_free(recv_data); goto start; } send(tcp_clint_sock, send_data, strlen(send_data), 0); //链接建立 while (1) { /* 从sock 连接中接收最大BUFSZ - 1 字节数据 */ bytes_received = recv(tcp_clint_sock, recv_data, BUF - 1, 0); if (bytes_received <= 0) { /* 接收失败,关闭这个连接 */ lwip_close(tcp_clint_sock); break; } rt_sem_take(tcp_sem_lock, RT_WAITING_FOREVER); //取得信号量锁死 recv_data[bytes_received] = '�'; send(tcp_clint_sock, "ok ", strlen("ok "), 0); //回复服务器已经收到数据 memcpy(Tcp_Buf, recv_data, bytes_received); //复制接收缓存到暂存BUF rt_sem_release(tcp_sem_lock);//释放信号锁 rt_mb_send(&tcp2si_mbox, bytes_received); //接收到数据发送邮箱 } } } ```
查看更多
11
个回答
默认排序
按发布时间排序
tanghong668
2013-12-19
这家伙很懒,什么也没写!
试一试下面的代码: ```c #define BUF_SIZE 512 static char buffer[BUF_SIZE]; static int socket; void tcp_client_thread(void *p) { while(1) { while((socket = lwip_socket(AF_INET, SOCK_STREAM, 0)) == -1) { rt_thread_delay(RT_TICK_PER_SECOND/5); continue; } lwip_setsockopt( socket, IPPROTO_TCP, TCP_NODELAY, &optval, sizeof(optval)); ServerAddr.sin_family = AF_INET; ServerAddr.sin_port = htons(devInfo.server_port); ServerAddr.sin_addr.s_addr = devInfo.server_ip.addr; rt_memset(&(ServerAddr.sin_zero),0, sizeof(ServerAddr.sin_zero)); if(connect(socket, (struct sockaddr *)&ServerAddr, sizeof(struct sockaddr)) == -1) { rt_thread_delay(RT_TICK_PER_SECOND/5); lwip_close(socket); continue; } lwip_send(socket, buffer, 10, MSG_DONTWAIT); printf("连接到服务器! "); memset(buffer, 0, sizeof(buffer)); time.tv_sec = 300; time.tv_usec = 0; while(1) { FD_ZERO(&readset); FD_SET(socket, &readset); ret = lwip_select(socket + 1, &readset, 0, 0, &time); if(ret > 0 && FD_ISSET(socket, &readset)) { len = lwip_recv(socket, buffer, sizeof(buffer), 0); if(len > 0) { rt_hw_led_on(LED4); data_handler(buffer, len); memset(buffer, 0, sizeof(buffer)); rt_thread_delay(RT_TICK_PER_SECOND/10); rt_hw_led_off(LED4); } else { lwip_close(socket); printf("连接关闭! "); break; } } else { //心跳包 char ch = 0xAB; if(lwip_send(socket, &ch, 1, MSG_DONTWAIT) == -1) { printf("连接异常! "); lwip_close(socket); break; } } } } } ```
hairui01234567
2013-12-18
这家伙很懒,什么也没写!
!!!
小ARM菜菜
2013-12-18
这家伙很懒,什么也没写!
[s:179] [s:175] [s:166] [s:163] [s:157] [s:154] [s:193] [s:194] [s:195] [s:182] [s:182] [s:182]
bernard
2013-12-18
这家伙很懒,什么也没写!
多线程操作同一个socket !!!
小ARM菜菜
2013-12-18
这家伙很懒,什么也没写!
也就说我心跳包要由连接线程自己操作喽,一个线程独享一个socket,貌似。。。。
bernard
2013-12-18
这家伙很懒,什么也没写!
用select,TCP编程是有些地方需要注意的,否则容易陷进去
小ARM菜菜
2013-12-18
这家伙很懒,什么也没写!
多谢
小ARM菜菜
2013-12-18
这家伙很懒,什么也没写!
非阻塞方式
小ARM菜菜
2013-12-18
这家伙很懒,什么也没写!
其实我这个程序完全是可以用的,只要不是连续的在很短时间内断开/连接断开/连接就不会有问题,就会自动重连不会死,只不过我还想更完善,下一步试试老大说的select!
小ARM菜菜
2014-01-16
这家伙很懒,什么也没写!
这个不行。可能不是你的程序有问题,而是我需要事件驱动型的
撰写答案
登录
注册新账号
关注者
0
被浏览
6k
关于作者
小ARM菜菜
这家伙很懒,什么也没写!
提问
10
回答
55
被采纳
0
关注TA
发私信
相关问题
1
freemodbus tcp
2
stm32f103 LWIP 2.0.2 TCP收发问题
3
AT_DEVICE TCP 接收大文件失败!
4
RT thread freemobus tcp通讯问题
5
hard fault on thread: tcpip
6
RT系统TCP收数据速度慢
7
TCP Client 断线重连
8
TCP数据包多包重合的问题
9
rtthread simulator中能够使用WIN10中得TCP/IP服务吗
10
lwip 跨网段ping不通的问题
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
最新文章
1
使用百度AI助手辅助编写一个rt-thread下的ONVIF设备发现功能的功能代码
2
RT-Thread 发布 EtherKit开源以太网硬件!
3
rt-thread使用cherryusb实现虚拟串口
4
《C++20 图形界面程序:速度与渲染效率的双重优化秘籍》
5
《原子操作:程序世界里的“最小魔法单位”解析》
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
WIZnet_W5500
UART
ota在线升级
PWM
cubemx
freemodbus
flash
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
Debug
编译报错
msh
SFUD
keil_MDK
rt_mq_消息队列_msg_queue
ulog
C++_cpp
at_device
本月问答贡献
踩姑娘的小蘑菇
7
个答案
3
次被采纳
a1012112796
13
个答案
2
次被采纳
张世争
9
个答案
2
次被采纳
rv666
5
个答案
2
次被采纳
用户名由3_15位
11
个答案
1
次被采纳
本月文章贡献
程序员阿伟
8
篇文章
2
次点赞
hhart
3
篇文章
4
次点赞
大龄码农
1
篇文章
5
次点赞
ThinkCode
1
篇文章
1
次点赞
Betrayer
1
篇文章
1
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部