TCP如此的不可靠吗?

zhxonmir2 2018-05-10 11:35:34
近日,写了个局域网内的 “服务器-客户端” 程序(都是linux的),我写的是服务端,客户端另外两个人写。
然后出现了个问题,数据经常不正确,后来,我帮他找到了问题,他们那边多线程使用同一个SOCKET进行发送数据,没加互斥,导致了数据交错。 然后那人就跟我说了,你程序应该判断这个数据是那个线程发过来的啊,说我的程序兼容性不好。
然后还给我讲了好多好多的网络编程技术(他说他以前是做4G网络通讯设备开发的,跟我讲TCP包头,IP包头什么的),其中有个关键点就是,2个程序之间TCP连接的时候,一方程序关闭或者电脑关闭或者拔掉网线,另一方是不知道的,发送方还可以继续发送数据,因为发送方只是将数据放入本地缓存中,并不知道也不管对方在不在, 所以,需要心跳包来维持TCP连接,根据心跳包丢失数量来确认网络已断,(我们之间是有做了心跳包的,一定时间内收不到他的数据,就会踢掉客户端),等等等等,跟我扯了半个多小时,指出我好多好多的错误,最后,跟我讲,这个互斥,我们这边可以加一下。
其他我都无所谓了,有一点“一方程序关闭或者电脑关闭或者拔掉网线,另一方是不知道”,如此地贬低TCP,我就不开心了,Stevens叔叔的《TCP/IP详解》的三卷我也粗粗地过了2遍了,虽说第二卷好些地方看不懂,但是我还是很相信TCP的可靠性的,我相信TCP不至于这么鸡肋,然后就写了个测试客户端程序跟我的程序进行通讯(个人习惯用VS,就拿VS写了一个客户端),经测试任意一方关闭程序,对方马上就可以知道啊,然后他跟我说,WINDOWS可以,linux不行;我就把测试客户端程序改了一下,linux下运行也是一方关闭另一方马上知道啊,然后他跟我说,拔网线肯定对方不知道,我要不要拔一下网线试试呢? 跟我讲网络编程知识的是我们部门大领导啊,我敢不敢再测一下拔网线呢?
...全文
1380 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
牧童吃五谷 2018-06-04
  • 打赏
  • 举报
回复
对不起,操作失误,多发了一次: 1.如果是拔掉的是你的计算机和交换机之间的网线,而对方的网线正常,那么对方确实是不知道 2.如果是你的进程关闭的话,对方应该会收到网络断开命令的 3.如果进程被任务管理器强制关闭的话,不知道对方是否会知道,但我想可能会知道的吧(我不确定的) 4.TCP通讯是应该做心跳的
牧童吃五谷 2018-06-04
  • 打赏
  • 举报
回复
1.如果是拔掉的是你的计算机和交换机之间的网线,那么对方确实是不知道的但前提条件是拔你的电脑到交换机的网线,而对方的计算机网线如果正常连接到计算机的话,是正常的情况下,确实不知道的
lttxlttxlttx 2018-06-02
  • 打赏
  • 举报
回复
可能是防火墙的原因。TCP依赖于网络的硬件可靠性。
zhxonmir2 2018-05-16
  • 打赏
  • 举报
回复
引用 3 楼 laizx 的回复:
1. 正常的断线,无论是拔网线还是主动断掉,肯定双方都可以检测到的 2. 有一种情况可能检测不到,就是从链路层断开连接了,这个必须通过设置心跳包来自动管理 3. 判断数据从哪个线程过来,这个明显属于应用层面的工作了。你们定义一个简单的交互协议就可以解决了(比如带上一个唯一的ID之类的),同TCP通讯没有关系的。
没太看明白~~~ 我是有做了心跳包的,接收也是有设置了超时的
zhxonmir2 2018-05-16
  • 打赏
  • 举报
回复
引用 2 楼 u011156900 的回复:
我试了一下强制关闭(kill -9)netcat的TCP连接,答案是kernel会自动发送FIN,ACK包正常结束连接,所以楼主前面的测试结果是正确的。 但设想一下拔网线的情况,这时是不可能有FIN,ACK包发出来的,所以双方都不会知道连接已经丢失,这时候一般是重传数次,然后报错。这个就不演示了,楼主可以用wireshark自己实验一下。
拔掉网线的时候,send的确没有返回失败,但是,dmesg 显示了好多的”found a client with no channel in the client's hash table",说明系统是知道拔掉网线了,现在的问题是程序如何获取到这个消息呢
天为峰 2018-05-12
  • 打赏
  • 举报
回复
1. 正常的断线,无论是拔网线还是主动断掉,肯定双方都可以检测到的 2. 有一种情况可能检测不到,就是从链路层断开连接了,这个必须通过设置心跳包来自动管理 3. 判断数据从哪个线程过来,这个明显属于应用层面的工作了。你们定义一个简单的交互协议就可以解决了(比如带上一个唯一的ID之类的),同TCP通讯没有关系的。
hexoxssaa 2018-05-11
  • 打赏
  • 举报
回复
我试了一下强制关闭(kill -9)netcat的TCP连接,答案是kernel会自动发送FIN,ACK包正常结束连接,所以楼主前面的测试结果是正确的。 但设想一下拔网线的情况,这时是不可能有FIN,ACK包发出来的,所以双方都不会知道连接已经丢失,这时候一般是重传数次,然后报错。这个就不演示了,楼主可以用wireshark自己实验一下。
cqyy725 2018-05-11
  • 打赏
  • 举报
回复
哈哈哈 ,那你要让你的领导重新学习一下tcp协议了

427

社区成员

发帖
与我相关
我的任务
社区描述
非技术问题的乐园
社区管理员
  • 非技术区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧