TCP请求超时后如何处理的问题

woshinia 2014-12-29 03:32:38
对于一个TCP长连接来说, 只要连接没有断开,正确的命令是一定可以收到Server的回复的。

但是网络状况不佳的情况下,不可能永远等待server的回复,通常会设置一个超时时间,一旦超过一定时间,就会认为失败。对于短连接来说,只要简单的断开连接就可以了,但是长连接的话,一般处理方式就是无视server返回的结果,如果server在超时时间后返回结果,直接丢弃。如果是一个读取数据的操作,这样做没有任何问题。

现在问题是,如果我有一个写操作命令发送给Server了,但是超过时间没有响应,应该怎么处理?比如说更改用户密码的命令,长连接是不能断开连接的,这时该怎么处理?(就算是短连接,是否也存在超时返回失败,但是实际密码已经更改成功的情况?)

个人想到的有:(1)若Server处理完密码更改任务完成后,还没发response,连接就因为网络异常断开了,似乎是无解,这个可以暂不考虑。所以以下都是不考虑网络中途异常断开的情况。

(2)超时后,发送cancel指令给server,取消密码更改命令,不过这会大大增加Server程序的复杂度,至少需要缓存之前的旧密码,cancel指令什么时候能达到server也是个问题,server上总不能无期限的保存这个旧密码吧。

(3)写操作不做超时机制,改成异步,一直等到结果返回为止,并且在结果返回前不允许再发送这个写操作命令。不过体验比较差,相当于一段时间内禁用了某功能。
...全文
3330 18 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
小麻侬 2015-01-07
  • 打赏
  • 举报
回复
引用 17 楼 woshinia 的回复:
[quote=引用 13 楼 wutaozhao 的回复:] [quote=引用 10 楼 woshinia 的回复:] [quote=引用 9 楼 wutaozhao 的回复:] 针对你上面这贴说的这种情况,如果是我,我就针对这种超时的请求,在下次发命令前先到服务器查询一下,如果上次执行成功,就不再重复发送
但是下次命令与上次命令参数可能是不同的,server怎么判断“上次执行“是哪一次呢?要精确比较的话,server就需要缓存大量的数据,到底要缓存多少条,这些数据要缓存多久也不知道。[/quote] 不知道你服务端的数据是怎么组织的,这种问题在很多系统都会是严重问题,比如计费系统,玩家充了钱,服务端也成功,但像你说的,客户端没收到回包,就需要客户端和服务器制定协议来处理这种情况。[/quote] 计费系统好像比较容易解决,就是定时(或者用户打开重新打开充值页面的时候)刷新下客户端的数据就行了。难道我
引用 13 楼 wutaozhao 的回复:
[quote=引用 10 楼 woshinia 的回复:] [quote=引用 9 楼 wutaozhao 的回复:] 针对你上面这贴说的这种情况,如果是我,我就针对这种超时的请求,在下次发命令前先到服务器查询一下,如果上次执行成功,就不再重复发送
但是下次命令与上次命令参数可能是不同的,server怎么判断“上次执行“是哪一次呢?要精确比较的话,server就需要缓存大量的数据,到底要缓存多少条,这些数据要缓存多久也不知道。[/quote] 不知道你服务端的数据是怎么组织的,这种问题在很多系统都会是严重问题,比如计费系统,玩家充了钱,服务端也成功,但像你说的,客户端没收到回包,就需要客户端和服务器制定协议来处理这种情况。[/quote] 比如就这个场景下,客户端没有收到回包,应该怎么处理? 1,直接提示操作失败(显然不可取) 2,超时后,不提示失败,而是发送命令查询结果,若查询也超时,则无限发送查询命令,直到成功为止? 3,不设置超时,一直等待回包,直到下次用户查询余额或者打开充值面板的时候,发送一次查询命令?[/quote] 客户端如果发现超时,就把这种请求上下文放到一个队列,最好是能持久化保存,比如写文件或写数据库,然后立马重发,如果每次重发都收不到回包,那么你的系统所在的网络就有很大问题,这时候就不是担心你程序的问题了,赶紧找负责网络的系统人员解决问题,等网络恢复,从文件和数据库把未决的请求处理掉,重发后,服务器可以根据订单id判断是否已有相同的订单,有的话,直接返回成功。一般来说,这种客户端收不到服务端返回的情况很少,即便碰到,重发个几次总会成功,这期间可能卡个几秒,对玩家来说,也是小概率事件,可以接受
woshinia 2015-01-06
  • 打赏
  • 举报
回复
引用 13 楼 wutaozhao 的回复:
[quote=引用 10 楼 woshinia 的回复:] [quote=引用 9 楼 wutaozhao 的回复:] 针对你上面这贴说的这种情况,如果是我,我就针对这种超时的请求,在下次发命令前先到服务器查询一下,如果上次执行成功,就不再重复发送
但是下次命令与上次命令参数可能是不同的,server怎么判断“上次执行“是哪一次呢?要精确比较的话,server就需要缓存大量的数据,到底要缓存多少条,这些数据要缓存多久也不知道。[/quote] 不知道你服务端的数据是怎么组织的,这种问题在很多系统都会是严重问题,比如计费系统,玩家充了钱,服务端也成功,但像你说的,客户端没收到回包,就需要客户端和服务器制定协议来处理这种情况。[/quote]
引用 14 楼 wxhxj0268 的回复:
正如楼上所说,如果真的这样,就需要由“机制”来保证,而并非你现在所操心的“程序处理流程”。 对于超时而言,如果你的系统设计中为小于1秒的话,估计超过这个值,即使你的程序不断开,TCP也会RET了,TCP中本身存在一个心跳。
引用 15 楼 lujunql 的回复:
在使用GPRS通讯时,会出现这种无响应超时的情况。需要一种事务机制来进行处理判断!
原来如此,谢谢各位指教。但有没有什么通用的做法呢?一般是用什么样的机制或协议?能否简单讲解下实现原理,或者是否有类似的开源代码,我去看看,这方面接触的比较少。
lujunql 2015-01-06
  • 打赏
  • 举报
回复
在使用GPRS通讯时,会出现这种无响应超时的情况。需要一种事务机制来进行处理判断!
笨笨仔 2015-01-06
  • 打赏
  • 举报
回复
正如楼上所说,如果真的这样,就需要由“机制”来保证,而并非你现在所操心的“程序处理流程”。 对于超时而言,如果你的系统设计中为小于1秒的话,估计超过这个值,即使你的程序不断开,TCP也会RET了,TCP中本身存在一个心跳。
woshinia 2015-01-06
  • 打赏
  • 举报
回复
引用 13 楼 wutaozhao 的回复:
[quote=引用 10 楼 woshinia 的回复:] [quote=引用 9 楼 wutaozhao 的回复:] 针对你上面这贴说的这种情况,如果是我,我就针对这种超时的请求,在下次发命令前先到服务器查询一下,如果上次执行成功,就不再重复发送
但是下次命令与上次命令参数可能是不同的,server怎么判断“上次执行“是哪一次呢?要精确比较的话,server就需要缓存大量的数据,到底要缓存多少条,这些数据要缓存多久也不知道。[/quote] 不知道你服务端的数据是怎么组织的,这种问题在很多系统都会是严重问题,比如计费系统,玩家充了钱,服务端也成功,但像你说的,客户端没收到回包,就需要客户端和服务器制定协议来处理这种情况。[/quote] 计费系统好像比较容易解决,就是定时(或者用户打开重新打开充值页面的时候)刷新下客户端的数据就行了。难道我
引用 13 楼 wutaozhao 的回复:
[quote=引用 10 楼 woshinia 的回复:] [quote=引用 9 楼 wutaozhao 的回复:] 针对你上面这贴说的这种情况,如果是我,我就针对这种超时的请求,在下次发命令前先到服务器查询一下,如果上次执行成功,就不再重复发送
但是下次命令与上次命令参数可能是不同的,server怎么判断“上次执行“是哪一次呢?要精确比较的话,server就需要缓存大量的数据,到底要缓存多少条,这些数据要缓存多久也不知道。[/quote] 不知道你服务端的数据是怎么组织的,这种问题在很多系统都会是严重问题,比如计费系统,玩家充了钱,服务端也成功,但像你说的,客户端没收到回包,就需要客户端和服务器制定协议来处理这种情况。[/quote] 比如就这个场景下,客户端没有收到回包,应该怎么处理? 1,直接提示操作失败(显然不可取) 2,超时后,不提示失败,而是发送命令查询结果,若查询也超时,则无限发送查询命令,直到成功为止? 3,不设置超时,一直等待回包,直到下次用户查询余额或者打开充值面板的时候,发送一次查询命令?
小麻侬 2015-01-05
  • 打赏
  • 举报
回复
引用 10 楼 woshinia 的回复:
[quote=引用 9 楼 wutaozhao 的回复:] 针对你上面这贴说的这种情况,如果是我,我就针对这种超时的请求,在下次发命令前先到服务器查询一下,如果上次执行成功,就不再重复发送
但是下次命令与上次命令参数可能是不同的,server怎么判断“上次执行“是哪一次呢?要精确比较的话,server就需要缓存大量的数据,到底要缓存多少条,这些数据要缓存多久也不知道。[/quote] 不知道你服务端的数据是怎么组织的,这种问题在很多系统都会是严重问题,比如计费系统,玩家充了钱,服务端也成功,但像你说的,客户端没收到回包,就需要客户端和服务器制定协议来处理这种情况。
版主大哥 2015-01-05
  • 打赏
  • 举报
回复
一般情况下,超时 5秒以上,网络速度也不至于这么慢啦,或者服务器处理慢(说明服务器逻辑有问题) 所以一般不会出现这种问题
版主大哥 2015-01-05
  • 打赏
  • 举报
回复
楼主的问题 也够呛人的 呵呵 设置超时了,server密码改成功了,客户端认为超时,断开连接重新连接,输入旧的密码不能登录(因为服务器密码已改)...
woshinia 2015-01-05
  • 打赏
  • 举报
回复
引用 9 楼 wutaozhao 的回复:
针对你上面这贴说的这种情况,如果是我,我就针对这种超时的请求,在下次发命令前先到服务器查询一下,如果上次执行成功,就不再重复发送
但是下次命令与上次命令参数可能是不同的,server怎么判断“上次执行“是哪一次呢?要精确比较的话,server就需要缓存大量的数据,到底要缓存多少条,这些数据要缓存多久也不知道。
小麻侬 2015-01-05
  • 打赏
  • 举报
回复
针对你上面这贴说的这种情况,如果是我,我就针对这种超时的请求,在下次发命令前先到服务器查询一下,如果上次执行成功,就不再重复发送
woshinia 2015-01-05
  • 打赏
  • 举报
回复
引用 7 楼 wxhxj0268 的回复:
[quote=引用 楼主 woshinia 的回复:] 个人想到的有:(1)若Server处理完密码更改任务完成后,还没发response,连接就因为网络异常断开了,似乎是无解,这个可以暂不考虑。所以以下都是不考虑网络中途异常断开的情况。 (2)超时后,发送cancel指令给server,取消密码更改命令,不过这会大大增加Server程序的复杂度,至少需要缓存之前的旧密码,cancel指令什么时候能达到server也是个问题,server上总不能无期限的保存这个旧密码吧。 (3)写操作不做超时机制,改成异步,一直等到结果返回为止,并且在结果返回前不允许再发送这个写操作命令。不过体验比较差,相当于一段时间内禁用了某功能。
对一个需要密码的网络服务而言,断开了就意味着要重新登录,因此,你的1、2问题应该不存在。而对需要长连的网络双方,都能通过心跳和TCP知道连接状态,发生断开时直接启动重连操作,我在长连网络试验以各种方式断开连接中的任意部分,当连接恢复后程序都能自愈,不会出现你所说的情况,我想问题出在总体设计而不是出在具体细节。[/quote]
引用 5 楼 oyljerry 的回复:
超时处理, 服务端是断开跟客户端连接 客户端是再次请求
我不是要考虑连接断开的情况,而是客户端与服务端写操作结果不一致的问题。如我发送一个修改密码的命令给server,server执行成功了,但是server发送response给client时,网络拥塞之类,造成客户端过了非常久才收到,客户端做超时处理时,认为失败了,那么此时客户端显示结果就和server端不一致了,这种情况网络未必会断开,可能只是偶尔拥塞了一下。而且所用为长连接,一般情况下不会去关闭连接。
xian_wwq 2014-12-31
  • 打赏
  • 举报
回复
超时处理从server侧入手比较好 server对于连接的client进行监测,一旦发现超时,则主动close socket 对于client来说,之前的连接失效 重新发起请求建立连接。
笨笨仔 2014-12-31
  • 打赏
  • 举报
回复
引用 楼主 woshinia 的回复:
个人想到的有:(1)若Server处理完密码更改任务完成后,还没发response,连接就因为网络异常断开了,似乎是无解,这个可以暂不考虑。所以以下都是不考虑网络中途异常断开的情况。 (2)超时后,发送cancel指令给server,取消密码更改命令,不过这会大大增加Server程序的复杂度,至少需要缓存之前的旧密码,cancel指令什么时候能达到server也是个问题,server上总不能无期限的保存这个旧密码吧。 (3)写操作不做超时机制,改成异步,一直等到结果返回为止,并且在结果返回前不允许再发送这个写操作命令。不过体验比较差,相当于一段时间内禁用了某功能。
对一个需要密码的网络服务而言,断开了就意味着要重新登录,因此,你的1、2问题应该不存在。而对需要长连的网络双方,都能通过心跳和TCP知道连接状态,发生断开时直接启动重连操作,我在长连网络试验以各种方式断开连接中的任意部分,当连接恢复后程序都能自愈,不会出现你所说的情况,我想问题出在总体设计而不是出在具体细节。
oyljerry 2014-12-29
  • 打赏
  • 举报
回复
超时处理, 服务端是断开跟客户端连接 客户端是再次请求
一桶姜山 2014-12-29
  • 打赏
  • 举报
回复
超时服务器肯定也会断开,客户端收到服务端断开的消息就知道该重连了。 如果网络差得非常厉害客户端收不到服务端返回的消息那我估计客户端主动断了再重连也一样会失败。 这种网络情况下还考虑让客户端做到正确显示我觉得有点浪费精力了
赵4老师 2014-12-29
  • 打赏
  • 举报
回复
请求超时就当网络断开。 重连。
赵4老师 2014-12-29
  • 打赏
  • 举报
回复
网络中途早晚是要断开的。

18,363

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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