硬汉嵌入式论坛

 找回密码
 立即注册
查看: 4320|回复: 20
收起左侧

[RL-TCPnet] 关于socket通讯过程中,断开网线的处理方法提问

[复制链接]

3

主题

82

回帖

91

积分

初级会员

积分
91
发表于 2019-3-12 11:33:03 | 显示全部楼层 |阅读模式
硬汉,你好,前阵子串口转以太网的程序基本写出来了,现在遇到了点问题
运行版本如下:
RTX V4.81(RTOS V1)+network v7.10(应该是当前最新的了)

硬件型号如下:
LPC176X(MAC)+KSZ8041(PHY)

问题条件:
1.在network协议栈内,有个自带的回调函数:void netETH_Notify (...)可以快速的反应出网线插拔状态
2.socket为BSD Client(暂且命名为sock_Client),长连接模式,阻塞方式
3.开启了socket后,连接正常,通讯正常
5.拔开后快速插回,重新连接上服务器端口需要等待很久
4.在socket通讯过程中,把网线拔掉,然后回调函数netETH_Notify( )判断出网线已拔,马上进行closesocket(sock_Client),可是没效果,状态检测socket仍然处于正常连接状态,需要等待30S左右才能跳出此状态

请教:
有没有方法可以强制关闭SOCKET?无论SOCKET处于什么状态。(现在我的处理方案是检测到网线断开,就立刻重启模块Reset_Handler(),虽然不影响使用,但是还是想看看有没有其他办法)

谢谢!

回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107488
QQ
发表于 2019-3-12 11:43:42 | 显示全部楼层
V7.X还没有顾上研究插拔问题。

之前的版本研究过不少
TCPnet处理网线随意插拔的注意事项总结,更新时间2016-08-20
http://www.armbbs.cn/forum.ph ... id=21045&fromuid=58

TCP Client断开网络和插拔网线,重新连接的几种情况分析
http://www.armbbs.cn/forum.ph ... id=29859&fromuid=58






回复

使用道具 举报

3

主题

82

回帖

91

积分

初级会员

积分
91
 楼主| 发表于 2019-3-12 12:04:06 | 显示全部楼层
eric2013 发表于 2019-3-12 11:43
V7.X还没有顾上研究插拔问题。

之前的版本研究过不少

谢谢硬汉,之前有拜读过这两篇文章,提供了一些思路,谢谢。
有些地方没太搞懂,我用KEIL的NETWORK检测窗口,拔网线后这个SOCKET还是在RECV那阻塞着,重新连接上网线后,用WIRESHARK抓包,发现会发送一些包过来,提示信息是TCP WINDOW FULL,然后要等30S左右,才会重新开始发SYN(应该是正好跳出了RECV(),重新CONNECT()),有没有函数可以不管SOCKET是处于什么状态的,直接强制关闭这个SOCKET
谢谢硬汉百忙中回答我的问题
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107488
QQ
发表于 2019-3-12 12:22:26 | 显示全部楼层
Nesayx 发表于 2019-3-12 12:04
谢谢硬汉,之前有拜读过这两篇文章,提供了一些思路,谢谢。
有些地方没太搞懂,我用KEIL的NETWORK检测 ...

我之前使用的VNC没有这个问题,是用的BSD Socket
回复

使用道具 举报

3

主题

82

回帖

91

积分

初级会员

积分
91
 楼主| 发表于 2019-3-18 15:59:16 | 显示全部楼层
eric2013 发表于 2019-3-12 12:22
我之前使用的VNC没有这个问题,是用的BSD Socket

硬汉,你好,打扰了,我在这接着问些问题!上次那个网线插拔的问题我就暂且用RESET解决了。
现在有个新的问题,我用的是BSD_Socket作为客户端,正常连接情况下没问题。现在我测试了一下如下图的情况

就是在通讯过程中,将服务端的网线拔掉,然后串口接着发送数据,程序没过多久就进入HardFault_Handler.
我调试过程中,看了send();recive的返回值跟正常连接的时候一样。现在想找到一个标志,或者事件,可以判断远程服务端非法断开的。
或者说有没有别的办法可以处理这种情况
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107488
QQ
发表于 2019-3-18 16:37:38 | 显示全部楼层
Nesayx 发表于 2019-3-18 15:59
硬汉,你好,打扰了,我在这接着问些问题!上次那个网线插拔的问题我就暂且用RESET解决了。
现在有个新 ...

有个keep alive心跳包,你使能下,远程服务器中断,应该会有回调消息的,你测序下是不是有
回复

使用道具 举报

3

主题

82

回帖

91

积分

初级会员

积分
91
 楼主| 发表于 2019-3-18 17:01:09 | 显示全部楼层
硬汉大佬,刚刚测了一下,我把KEEPALIVE设置为40s,然后这40s没有通过send()发送任何数据,发现正常了,socket被正常关闭了,如果在这40s使用了send()发送数据,程序就崩溃(HardFault_Handler)。可是,在实际项目中,就算把KEEPALIVE设置为1s,也是有概率让程序崩溃的,因为串口发送数据的时间是不确定的,所以更好的办法让程序稳定运行(程序一崩,在项目里就会要断电重启模块,感觉要被投诉)
回复

使用道具 举报

36

主题

1449

回帖

1557

积分

至尊会员

积分
1557
发表于 2019-3-18 18:12:55 | 显示全部楼层
Nesayx 发表于 2019-3-18 17:01
硬汉大佬,刚刚测了一下,我把KEEPALIVE设置为40s,然后这40s没有通过send()发送任何数据,发现正常了,so ...

http://www.armbbs.cn/forum.php?m ... 7%C9%E3%CF%F1%CD%B7   这个例程做了网线插拔的应用,使用PHY中断即可。网线重新插入,再次识别网络即可
回复

使用道具 举报

3

主题

82

回帖

91

积分

初级会员

积分
91
 楼主| 发表于 2019-3-18 18:45:03 | 显示全部楼层
sanit 发表于 2019-3-18 18:12
http://www.armbbs.cn/forum.php?mod=viewthread&tid=87016&highlight=%CD%F8%C2%E7%C9%E3%CF%F1%CD%B ...

谢谢你的回复,网线插拔的问题暂时解决了
现在遇到的问题是 我手上做着一个“以太网转串口”的模块,今天测试了一个环节
这个环节就像我上面那幅图一样,模块作为客户端(服务端和客户端中间是有交换机的,不是直连),去连接服务端,正常通讯下收发没有问题,
现在是如果服务端那方非法断开(比如服务端的网线突然断了),在bsd_socket层是感知不到,此时串口收到消息,依然会按照正常流程那样,调用SEND()函数去发送数据,这个时候,模块就会进入HardFault_Handler。
按照硬汉大佬的测试方法测了一下,把KEEPALIVE的时间调成40s,在发送服务端非法断开到模块发送keep-alive包期间,不通过send()发送数据,程序可以正常关闭客户端socket。只要发了,运行一段时间,就崩溃进入HardFault_Handler了。
我想了一下,就是把keep-alive改成1s发一次,也是治标不治本,只能说减少崩溃概率,因为在项目中,串口端是不定时发送数据的。
所以在此问问各位大佬,有没有什么好办法!谢谢大家
回复

使用道具 举报

36

主题

1449

回帖

1557

积分

至尊会员

积分
1557
发表于 2019-3-18 19:14:46 | 显示全部楼层
Nesayx 发表于 2019-3-18 18:45
谢谢你的回复,网线插拔的问题暂时解决了
现在遇到的问题是 我手上做着一个“以太网转串口”的模块,今 ...

你这个实验我接着也要做了验证一下,我最近也做网络的项目,等待我的回复。
回复

使用道具 举报

3

主题

82

回帖

91

积分

初级会员

积分
91
 楼主| 发表于 2019-3-18 19:22:02 | 显示全部楼层
sanit 发表于 2019-3-18 19:14
你这个实验我接着也要做了验证一下,我最近也做网络的项目,等待我的回复。

OK,谢谢了。可能我两版本不太一样,我用的最新的v7.1版本的
回复

使用道具 举报

36

主题

1449

回帖

1557

积分

至尊会员

积分
1557
发表于 2019-3-18 20:12:44 | 显示全部楼层
Nesayx 发表于 2019-3-18 19:22
OK,谢谢了。可能我两版本不太一样,我用的最新的v7.1版本的

确实不一样,我用的还是V4.70
回复

使用道具 举报

3

主题

82

回帖

91

积分

初级会员

积分
91
 楼主| 发表于 2019-3-18 20:48:49 | 显示全部楼层
sanit 发表于 2019-3-18 20:12
确实不一样,我用的还是V4.70

因为用的MDK5.23,配置起来图方便,然后能直接调用NETWORK窗口,就直接上7.1了
回复

使用道具 举报

36

主题

1449

回帖

1557

积分

至尊会员

积分
1557
发表于 2019-3-18 21:11:33 | 显示全部楼层
Nesayx 发表于 2019-3-18 20:48
因为用的MDK5.23,配置起来图方便,然后能直接调用NETWORK窗口,就直接上7.1了

你直接拔掉设备的网线,如果不是根据PHY中断判断断开了,上面应用层也不会及时通知网线断开吧?
回复

使用道具 举报

36

主题

1449

回帖

1557

积分

至尊会员

积分
1557
发表于 2019-3-18 22:32:14 | 显示全部楼层
我用V4.7版本也是同样问题,就是通讯过程中如果强制拔掉网线,可能导致内部TCPNET API函数阻塞,有没有方法判断网线断开了呢?如果靠中断来识别,感觉不是很及时。老大,有没有方法解决一下?
回复

使用道具 举报

3

主题

82

回帖

91

积分

初级会员

积分
91
 楼主| 发表于 2019-3-18 22:42:20 | 显示全部楼层
我用的v7.10版本里面,有一个判断网络连接状态的回调函数,如果是连接模块的网线掉了,这个回调函数还是反应很快的
回复

使用道具 举报

36

主题

1449

回帖

1557

积分

至尊会员

积分
1557
发表于 2019-3-19 09:01:28 | 显示全部楼层
Nesayx 发表于 2019-3-18 22:42
我用的v7.10版本里面,有一个判断网络连接状态的回调函数,如果是连接模块的网线掉了,这个回调函数还是反 ...

我测试UDP发送的时候断开网线没事的,因为UDP不需要等待应答。但是TCP正在发送的时候,断开网线,会导致一直等待应答,这样就不好了。我试着换个方法处理试试
回复

使用道具 举报

3

主题

82

回帖

91

积分

初级会员

积分
91
 楼主| 发表于 2019-3-19 12:16:09 | 显示全部楼层
找到个办法,在发送的任务里不用bsd_socket的send(),直接调用TCP_SEND,每次发送前判断tcp是否ready,不过不知道为啥,要两次使用两次tcp_send后才判断不符合ready状态,不过程序不会崩溃了,还是比较满意的
回复

使用道具 举报

3

主题

82

回帖

91

积分

初级会员

积分
91
 楼主| 发表于 2019-3-19 12:17:39 | 显示全部楼层
打多了个两次,要使用两次tcp_send后才判断为非ready状态
回复

使用道具 举报

36

主题

1449

回帖

1557

积分

至尊会员

积分
1557
发表于 2019-3-19 14:25:36 | 显示全部楼层
Nesayx 发表于 2019-3-19 12:17
打多了个两次,要使用两次tcp_send后才判断为非ready状态

截图看一下
回复

使用道具 举报

3

主题

82

回帖

91

积分

初级会员

积分
91
 楼主| 发表于 2019-3-19 14:56:24 | 显示全部楼层

+q 561514065
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-6-4 06:59 , Processed in 0.299713 second(s), 26 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表