采用TCP时,应用层需要超时重传吗?

小竹z 2014-09-04 09:49:10
工作需要给第三方通信,采用tcp协议,文档中要求在发送消息一定时间内,未收到对方回复,需要重发。tcp本身是提供这种机制的额,为什么还需要应用层超时重发?如果之前一条消息在指定时间内未收到回复,重传了,但之前那条消息后来又被对方收到了,岂不是一条消息被发送了2次?
...全文
571 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
小竹z 2014-11-04
  • 打赏
  • 举报
回复
谢谢大家了,结论:tcp保证数据可靠传输,传输成功不代表被对方逻辑层成功处理,此时超时重传解决网络传输功能,但没有被逻辑层成功处理情况,有可能是对方应用程序崩溃了,重启后可继续处理~
赵4老师 2014-09-09
  • 打赏
  • 举报
回复
不知道有多少前人掉在TCP Socket send(人多)send(病少)send(财富) recv(人多病)recv(少财富) 陷阱里面啊! http://bbs.csdn.net/topics/380167545
zilaishuichina 2014-09-09
  • 打赏
  • 举报
回复
引用 8 楼 zgxyz2010 的回复:
网络层也是我自己写,如果网络层相对于应用层丢包,说明程序存在bug,即使提供了重转,不一样会被丢掉?
首先lz需要明白的是,send的返回OK != 数据被对方成功收到 ,且,数据被对方成功受到 != 数据被对方逻辑成功处理 举个极端的例子: 对方收到包,但是还没来的及处理,程序崩掉了,这个时候你的网络层显示的显然是对方收到了(确实也是对方收到了),但是对方并没有正确处理这个包,这个时候从逻辑上讲,你应该需要重发的,保证对方正确处理完毕。
小竹z 2014-09-09
  • 打赏
  • 举报
回复
引用 3 楼 truelance 的回复:
1. 判断重传或重复的标记不一样。在TCP层,头部有一个32位的序号,在接收侧有一个滑动窗口,只有接收到的消息序号在窗口范围内才被接收,否则被当做非法消息丢弃;在窗口范围内的每个序号都有是否已收到的标记,因此对重发的消息也不会重复接收。 如果在应用层进行重发,你需要自己做类似的事情。 2. 如果底层通信质量不好,TCP可能会断链重连,或者序号检测发现异常重置序号。这些情况下TCP层都会丢帧,应用层如果有重要的消息还是要自己做重传。
你的意思是底层提供在检测到链接断开后自动重连,应用层通过超时重传机制重发重要的数据?
小竹z 2014-09-09
  • 打赏
  • 举报
回复
引用 2 楼 zilaishuichina 的回复:
tcp本身是提供这种机制的额,为什么还需要应用层超时重发? 这个是跟网络层的实现有关的,不知道你的网络层是自己写的,还是用的写好,或者是第三方的。 tcp相对于你的网络层保证不丢包,不代表网络层相对于你的应用层保证不丢包。 这个和具体的网络实现有关 重传了,但之前那条消息后来又被对方收到了,岂不是一条消息被发送了2次? 确实会存在这种情况,但是这个不是发送方需要考虑的问题,而是接收方需要考虑的. 解决办法:比如需要在消息里面加上sessionid,一个逻辑包对应一个唯一的sessionid,重发时不改变这个sessionid,接收端收到重复的sessionid就不处理。
网络层也是我自己写,如果网络层相对于应用层丢包,说明程序存在bug,即使提供了重转,不一样会被丢掉?
勤奋的小游侠 2014-09-04
  • 打赏
  • 举报
回复
tcp的超时控制不是你能设置的,所有的tcp超时都是用系统的时间设定,而且这个时间很长,超时的结果就是断开连接。 和你应用要达到的目的显然差很远
勤奋的小游侠 2014-09-04
  • 打赏
  • 举报
回复
tcp的超时控制不是你能设置的,所有的tcp超时都是用系统的时间设定,而且这个时间很长,超时的结果就是断开连接。 和你应用要达到的目的显然差很远
www_adintr_com 2014-09-04
  • 打赏
  • 举报
回复
用 TCP 的话,是超时后链接断开了,你重新建立了链接,才需要重新发送之前发送的数据。 如果链接没有出现异常, TCP 会一直重试你放到发送缓冲区中的数据,直到收到对方确认或是重试次数太多失败后在链接上返回异常。
mujiok2003 2014-09-04
  • 打赏
  • 举报
回复
TCP本身的time_out一般不能控制,跟实现有关, 而且一般比较长。
熊熊大叔 2014-09-04
  • 打赏
  • 举报
回复
1. 判断重传或重复的标记不一样。在TCP层,头部有一个32位的序号,在接收侧有一个滑动窗口,只有接收到的消息序号在窗口范围内才被接收,否则被当做非法消息丢弃;在窗口范围内的每个序号都有是否已收到的标记,因此对重发的消息也不会重复接收。 如果在应用层进行重发,你需要自己做类似的事情。 2. 如果底层通信质量不好,TCP可能会断链重连,或者序号检测发现异常重置序号。这些情况下TCP层都会丢帧,应用层如果有重要的消息还是要自己做重传。
zilaishuichina 2014-09-04
  • 打赏
  • 举报
回复
tcp本身是提供这种机制的额,为什么还需要应用层超时重发? 这个是跟网络层的实现有关的,不知道你的网络层是自己写的,还是用的写好,或者是第三方的。 tcp相对于你的网络层保证不丢包,不代表网络层相对于你的应用层保证不丢包。 这个和具体的网络实现有关 重传了,但之前那条消息后来又被对方收到了,岂不是一条消息被发送了2次? 确实会存在这种情况,但是这个不是发送方需要考虑的问题,而是接收方需要考虑的. 解决办法:比如需要在消息里面加上sessionid,一个逻辑包对应一个唯一的sessionid,重发时不改变这个sessionid,接收端收到重复的sessionid就不处理。
jwj070524 2014-09-04
  • 打赏
  • 举报
回复
我猜应该是显式的收到对方的ACK后才发下一个包?

64,682

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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