做了个板子,stm32f429+rtthread,板子做tcp client,通过网线连接pc。
实验过程中发现,如果通讯过程中拔掉网线,板子并不知道socket断开了。再插上网线,则通讯不成功了。
我想让板子能检测出网线是否故障,故障的话,重新建立socket连接。
群里朋友说select方法里有个参数是检测故障的,我搜了下:
int select(int maxfdp,fd_set *readfds,fd_set *writefds,fd_set *errorfds,struct timeval *timeout);
errorfds估计是,但是不知道改怎么用?
还有朋友说用link down,拔开网线后,调试串口 确实打印出了Link down。也许能用这个,linkdown后重启板子?
还有朋友说用心跳,不懂啊,心跳怎么搞?
离线
#if (LWIP_TCP_KEEPALIVE == 0)
#error "LWIP_TCP_KEEPALIVE must enable"
#endif
rt_err_t socket_config(void)
{
int keepalive = 1; //Enable keepalive.
int keepidle = 60; //idle time is 60s.
int keepinterval = 5; //sending interval of detective packet
int keepcount = 3; //detective count.
int flag = 1;
if (setsockopt(socket_fd, SOL_SOCKET, SO_KEEPALIVE, (void *)&keepalive, sizeof(keepalive)) < 0)
{
LOG("set Keep-Alive attribute failed\n");
return -RT_ERROR;
}
setsockopt(socket_fd, IPPROTO_TCP, TCP_KEEPIDLE, (void*)&keepidle , sizeof(keepidle));
setsockopt(socket_fd, IPPROTO_TCP, TCP_KEEPINTVL, (void *)&keepinterval , sizeof(keepinterval));
setsockopt(socket_fd, IPPROTO_TCP, TCP_KEEPCNT, (void *)&keepcount , sizeof(keepcount));
setsockopt(socket_fd, IPPROTO_TCP, TCP_NODELAY, (void *)&flag , sizeof(flag));
return RT_EOK;
}
{
struct timeval timeout;
timeout.tv_sec = 1;
timeout.tv_usec = 0;
setsockopt(connected, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
}
离线
心跳应该就是指每过一段时间 client 就给 server 发点小数据,然后等 server 回复吧。如果回复超时或者根本没有回复,那你就知道网线或者server出问题了。如果 server 每过一段时间没有收到client 的心跳请求的话,server 也就知道网线或者client出问题了。
带网络的这种app,直接上F1C多香哈哈,干嘛还用stm32呢
最近编辑记录 unturned3 (2021-09-15 10:16:14)
离线
linux编程岂不是更难?光个移植系统估计就能难住我。
离线
linux上有ethtool接口可以直接看到link状态
离线
linux编程岂不是更难?光个移植系统估计就能难住我。
不会吧,Linux 的各种库用 buildroot 编译了随便用,写个 C 程序调用 API 就搞定了。
而且内核还会帮你封装很多东西,比如你要检测 eth0 的连接是不是好的,直接查看 /sys/class/net/eth0/carrier, /sys/class/net/eth0/operstate 文件内容就行了,根本不需要用什么心跳之类的操作
离线
@aozima
确实有用,加上这段代码后断开网线,大约60秒后,socket会recv()出错。
我这里的处理上关闭socket,让后跳出循环,重建socket再连接。
后来试了多次,发现,拔掉网线一会后,如果过了比较短的一段时间,再插上网线,这时,仍可以通讯,没有重连。
但是拔掉网线超过了大约30秒后,插上网线,貌似可以通讯一条,然后就通讯不上了,等到60秒以后,socket recv()出错,关闭socket,跳出内层循环,在外层循环里重建socket及重新connect(),但是总是连不上。
请问,这是为什么?
离线
重新connect 有换src port吗?
离线
重新connect 有换src port吗?
没明白src port指的是什么。
是指tcp server的地址和端口吗?这个是不变的。
socket是重新建的。
离线
真的是很烦 说:重新connect 有换src port吗?
没明白src port指的是什么。
是指tcp server的地址和端口吗?这个是不变的。socket是重新建的。
是client用的源端口
ip 通讯的五元组: server ip + dest port + proto + client ip + src port
很有可能对方的tcp session还在, 如果你还是用相同的src port去连接对方, 对方未必搭理你, 防火墙也有可能拦下这种SYN
离线
@真的是很烦
那么,这个src port,该如何换呢?请教。
离线