您尚未登录。

楼主 # 2021-09-15 08:59:38

Gentlepig
会员
注册时间: 2018-10-24
已发帖子: 1,204
积分: 1140.5

tcp socket编程能否判断网线是否断了?

做了个板子,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后重启板子?

还有朋友说用心跳,不懂啊,心跳怎么搞?

离线

#1 2021-09-15 09:55:42

aozima
会员
所在地: 深圳
注册时间: 2019-05-25
已发帖子: 449
积分: 316.5
个人网站

Re: tcp socket编程能否判断网线是否断了?

#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));			
}

离线

#2 2021-09-15 10:13:08

unturned3
会员
注册时间: 2020-07-01
已发帖子: 262
积分: 300

Re: tcp socket编程能否判断网线是否断了?

心跳应该就是指每过一段时间 client 就给 server 发点小数据,然后等 server 回复吧。如果回复超时或者根本没有回复,那你就知道网线或者server出问题了。如果 server 每过一段时间没有收到client 的心跳请求的话,server 也就知道网线或者client出问题了。

带网络的这种app,直接上F1C多香哈哈,干嘛还用stm32呢

最近编辑记录 unturned3 (2021-09-15 10:16:14)

离线

楼主 #3 2021-09-15 14:19:53

Gentlepig
会员
注册时间: 2018-10-24
已发帖子: 1,204
积分: 1140.5

Re: tcp socket编程能否判断网线是否断了?

linux编程岂不是更难?光个移植系统估计就能难住我。

离线

#4 2021-09-15 17:10:46

shaoxi2010
会员
注册时间: 2019-06-13
已发帖子: 367
积分: 316

Re: tcp socket编程能否判断网线是否断了?

linux上有ethtool接口可以直接看到link状态

离线

#5 2021-09-15 17:12:54

unturned3
会员
注册时间: 2020-07-01
已发帖子: 262
积分: 300

Re: tcp socket编程能否判断网线是否断了?

Gentlepig 说:

linux编程岂不是更难?光个移植系统估计就能难住我。

不会吧,Linux 的各种库用 buildroot 编译了随便用,写个 C 程序调用 API 就搞定了。

而且内核还会帮你封装很多东西,比如你要检测 eth0 的连接是不是好的,直接查看 /sys/class/net/eth0/carrier, /sys/class/net/eth0/operstate 文件内容就行了,根本不需要用什么心跳之类的操作

离线

楼主 #6 2021-09-16 16:36:35

Gentlepig
会员
注册时间: 2018-10-24
已发帖子: 1,204
积分: 1140.5

Re: tcp socket编程能否判断网线是否断了?

@aozima

确实有用,加上这段代码后断开网线,大约60秒后,socket会recv()出错。
我这里的处理上关闭socket,让后跳出循环,重建socket再连接。

后来试了多次,发现,拔掉网线一会后,如果过了比较短的一段时间,再插上网线,这时,仍可以通讯,没有重连。
但是拔掉网线超过了大约30秒后,插上网线,貌似可以通讯一条,然后就通讯不上了,等到60秒以后,socket recv()出错,关闭socket,跳出内层循环,在外层循环里重建socket及重新connect(),但是总是连不上。
请问,这是为什么?

离线

#7 2021-09-16 20:08:22

真的是很烦
会员
注册时间: 2018-10-08
已发帖子: 154
积分: 146.5

Re: tcp socket编程能否判断网线是否断了?

重新connect 有换src port吗?

离线

楼主 #8 2021-09-17 08:51:27

Gentlepig
会员
注册时间: 2018-10-24
已发帖子: 1,204
积分: 1140.5

Re: tcp socket编程能否判断网线是否断了?

真的是很烦 说:

重新connect 有换src port吗?

没明白src port指的是什么。
是指tcp server的地址和端口吗?这个是不变的。

socket是重新建的。

离线

#9 2021-09-17 10:15:05

真的是很烦
会员
注册时间: 2018-10-08
已发帖子: 154
积分: 146.5

Re: tcp socket编程能否判断网线是否断了?

Gentlepig 说:
真的是很烦 说:

重新connect 有换src port吗?

没明白src port指的是什么。
是指tcp server的地址和端口吗?这个是不变的。

socket是重新建的。

是client用的源端口
ip 通讯的五元组:    server ip + dest port  + proto + client ip + src port

很有可能对方的tcp session还在,   如果你还是用相同的src port去连接对方, 对方未必搭理你, 防火墙也有可能拦下这种SYN

离线

楼主 #10 2021-09-17 14:19:36

Gentlepig
会员
注册时间: 2018-10-24
已发帖子: 1,204
积分: 1140.5

Re: tcp socket编程能否判断网线是否断了?

@真的是很烦
那么,这个src port,该如何换呢?请教。

离线

页脚

工信部备案:粤ICP备20025096号 Powered by FluxBB

感谢为中文互联网持续输出优质内容的各位老铁们。 QQ: 516333132, 微信(wechat): whycan_cn (哇酷网/挖坑网/填坑网) service@whycan.cn