关于 bsd socket send() 方法的超时设置,恳请高手指点迷津

beMyBest 2014-09-23 08:59:48
最近写了一个 ios 设备上的小网络游戏,
因为移动设备经常出现网络连接断开的问题,
所以在调用 send 方法时,经常会出现发不出消息的情况。
之前我误认为 send 的整形返回值就是发送出去的数据长度了,
后来经过测试才发现那就是坑爹,在网络断开的情况下,
send 照样原封不动的返回待发送数据的长度,而且是立马返回的,
立马返回这个很坑爹,再怎么说网络传输也需要花时间吧?
我不太明白 send 这个返回值存在的意图是什么,求高手解答一下。。
关于这个问题,我也查过不少资料,花费了很多时间,但是终究找不到一个漂亮的解决方案,
侦测 socket 的连接状态,这个之前看到过一篇帖子,是针对 台式机的,
大意就是网线拔掉了,执行网络 io,结果很长时间都得不到回馈,连接状态的感知令之头疼。。。
send 能够设置超时么,该如何去设置呢?
附带问一下,如果断线情况下发送一个消息,三分钟后网络重新链接上,断线情况下发送的消息对端在此时能收到么?
...全文
204 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
gfchen1989 2014-09-25
  • 打赏
  • 举报
回复
socket机制,send是发送到send缓冲区的,然后由底层自己的协议发送到对端的recv缓冲区的,recv从recv缓冲区中取数据
beMyBest 2014-09-25
  • 打赏
  • 举报
回复
引用 8 楼 max_min_ 的回复:
是只是复制到底层的IO缓冲,实际开发过程可能会遇到一直在阻塞,所以一般建议设置超时机制和心跳
哈哈,原来你装菜。超时机制和心跳要一起进行么?为什么呢?如果 socket 本身的超时机制有用的话,那还要心跳干嘛?反之,心跳都做了,还有必要在设置超时机制么?
max_min_ 2014-09-25
  • 打赏
  • 举报
回复
引用 9 楼 beMyBest 的回复:
引用 8 楼 max_min_ 的回复:
是只是复制到底层的IO缓冲,实际开发过程可能会遇到一直在阻塞,所以一般建议设置超时机制和心跳
哈哈,原来你装菜。超时机制和心跳要一起进行么?为什么呢?如果 socket 本身的超时机制有用的话,那还要心跳干嘛?反之,心跳都做了,还有必要在设置超时机制么?
心跳1分钟,你超时不可能也是1分钟吧?这就没什么效率可言了!socket本身超时机制用的少,不是很了解。估计是和本身的应用层的机制有所不同吧(猜测)
max_min_ 2014-09-24
  • 打赏
  • 举报
回复
检查返回值吧,网络断开了发送应该是立刻返回错误的send返回值应该是-1,errno应该是bad descript
beMyBest 2014-09-24
  • 打赏
  • 举报
回复
引用 3 楼 lovesmiles 的回复:
可以用setopt将socket的发送缓冲设置成只有一个字节,同步阻塞send,再设置发送超时,这样没有真正发送完,send是不会返回的。查下setsockopt函数的各个参数和用法。应该可以实现你想要的。
不太明白, 1.设置成只有一个字节, 2.同步阻塞 send 3.再设置发送超时 这三个操作应该是分开的把? 设置成只有一个字节,这么做会不会太极端,导致性能下降什么的? send 默认难道不是阻塞的? 发送超时的具体含义是什么?(这个东西我设置过,好像没有起作用,SO_SNDTIMEO, time_val{3, 0})
max_min_ 2014-09-24
  • 打赏
  • 举报
回复
引用 7 楼 beMyBest 的回复:
[quote=引用 5 楼 max_min_ 的回复:] 检查返回值吧,网络断开了发送应该是立刻返回错误的send返回值应该是-1,errno应该是bad descript
这个方法没用,socket 在侦测网络断开这点上很不灵敏,即使断开,返回值也是待发送数据的长度。 send 只是吧数据复制到系统的协议缓存,并不是将其确实发送到对端。[/quote] 是只是复制到底层的IO缓冲,实际开发过程可能会遇到一直在阻塞,所以一般建议设置超时机制和心跳
beMyBest 2014-09-24
  • 打赏
  • 举报
回复
引用 5 楼 max_min_ 的回复:
检查返回值吧,网络断开了发送应该是立刻返回错误的send返回值应该是-1,errno应该是bad descript
这个方法没用,socket 在侦测网络断开这点上很不灵敏,即使断开,返回值也是待发送数据的长度。 send 只是吧数据复制到系统的协议缓存,并不是将其确实发送到对端。
勤奋的小游侠 2014-09-24
  • 打赏
  • 举报
回复
引用 3 楼 lovesmiles 的回复:
[quote=引用 2 楼 beMyBest 的回复:] [quote=引用 1 楼 jerry_dqh 的回复:] 业务需要自己检测网络是否完好,client,serve之间可以使用心跳等检测, 对于send直接返回,数据首先提交送到系统协议栈中,所以直接返回,但这时并不代表数据立即被发送了,系统,网卡可能都还没有将数据发出去,但是数据应该处于待发送的状态了。 如果断线情况下发送一个消息,三分钟后网络重新链接上,断线情况下发送的消息对端在此时能收到么? 》》你使用的tcp,还是udp发送。如果使用tcp,数据对端可能还是收到的,因为数据缓存在本端的栈中。
嗯,了解了。我使用的时 tcp,我可不可以设定一个时间,如果超过了这个时间后我能将协议存储清空掉,因为此时我已经后悔了,不想3分钟前缓存的东西发出去了。[/quote] 可以用setopt将socket的发送缓冲设置成只有一个字节,同步阻塞send,再设置发送超时,这样没有真正发送完,send是不会返回的。查下setsockopt函数的各个参数和用法。应该可以实现你想要的。[/quote] send只是把东西复制到缓冲区,只要缓冲区不满,就不会阻塞,设置成1字节性能肯定有影响。
勤奋的小游侠 2014-09-23
  • 打赏
  • 举报
回复
引用 2 楼 beMyBest 的回复:
[quote=引用 1 楼 jerry_dqh 的回复:] 业务需要自己检测网络是否完好,client,serve之间可以使用心跳等检测, 对于send直接返回,数据首先提交送到系统协议栈中,所以直接返回,但这时并不代表数据立即被发送了,系统,网卡可能都还没有将数据发出去,但是数据应该处于待发送的状态了。 如果断线情况下发送一个消息,三分钟后网络重新链接上,断线情况下发送的消息对端在此时能收到么? 》》你使用的tcp,还是udp发送。如果使用tcp,数据对端可能还是收到的,因为数据缓存在本端的栈中。
嗯,了解了。我使用的时 tcp,我可不可以设定一个时间,如果超过了这个时间后我能将协议存储清空掉,因为此时我已经后悔了,不想3分钟前缓存的东西发出去了。[/quote] 可以用setopt将socket的发送缓冲设置成只有一个字节,同步阻塞send,再设置发送超时,这样没有真正发送完,send是不会返回的。查下setsockopt函数的各个参数和用法。应该可以实现你想要的。
beMyBest 2014-09-23
  • 打赏
  • 举报
回复
引用 1 楼 jerry_dqh 的回复:
业务需要自己检测网络是否完好,client,serve之间可以使用心跳等检测, 对于send直接返回,数据首先提交送到系统协议栈中,所以直接返回,但这时并不代表数据立即被发送了,系统,网卡可能都还没有将数据发出去,但是数据应该处于待发送的状态了。 如果断线情况下发送一个消息,三分钟后网络重新链接上,断线情况下发送的消息对端在此时能收到么? 》》你使用的tcp,还是udp发送。如果使用tcp,数据对端可能还是收到的,因为数据缓存在本端的栈中。
嗯,了解了。我使用的时 tcp,我可不可以设定一个时间,如果超过了这个时间后我能将协议存储清空掉,因为此时我已经后悔了,不想3分钟前缓存的东西发出去了。
碼上道 2014-09-23
  • 打赏
  • 举报
回复
业务需要自己检测网络是否完好,client,serve之间可以使用心跳等检测, 对于send直接返回,数据首先提交送到系统协议栈中,所以直接返回,但这时并不代表数据立即被发送了,系统,网卡可能都还没有将数据发出去,但是数据应该处于待发送的状态了。 如果断线情况下发送一个消息,三分钟后网络重新链接上,断线情况下发送的消息对端在此时能收到么? 》》你使用的tcp,还是udp发送。如果使用tcp,数据对端可能还是收到的,因为数据缓存在本端的栈中。

64,639

社区成员

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

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