如何解决 Socket 连接超时

最近两天 项目其中一台IM服务器的IM验证出现问题,进行用户IM注册时出现连接超时问题;

重启服务后,可以进行用户的IM注册验证,没有出现超时问题;但是等到半个钟一个钟(时间不定);

结果还是会有连接超时问题,所有单单是重启解决不了问题,也不可能一有问题就去重启服务

问题一:

登录服务器后台,使用netstat -ant命令查看当前网络状态:(此图是禁用IPV6后截图)


发现,输出中没有IM验证绑定的端口9193;但服务却是在运行;

然后使用 lsof -i:9193 能够获取到打开的文件记录,说明端口是启动的 ;但是,记录中的type是IPV6

猜测是否是因为使用了IPV6连接方式导致的问题,然后逐一测试80,8080等端口,发现凡是IPV6连接方式都不会显示

接下来,选择禁用IPV6:

打开/etc/sysctl.conf

在文件末尾添加:

# 禁用整个系统所有接口的IPv6
  net.ipv6.conf.all.disable_ipv6 = 1
  # 禁用某一个指定接口的IPv6(例如:eth0, lo)
  net.ipv6.conf.lo.disable_ipv6 = 1
  net.ipv6.conf.eth0.disable_ipv6 = 1
  在 /etc/sysctl.conf 使这些更改生效,运行以下命令:
  $ sudo sysctl -p /etc/sysctl.conf
  或者直接重启。


问题二:

解决上述问题后,重启服务后,连接超时异常还是出现;

使用netstat -ant查看连接状态,出现close_wait 状态;该问题是由于服务端或者

客户端其中某一方手动关闭了连接,服务端没有收到断开连接的请求,所以报错;

只能去查看源码:

查看源码,发现客户端和服务端的socket源码,都没有写异常的处理方式;

然后修改server源码,在异常中加上判断:(客户端的socket请求一样添加了处理)

1.判断socket是否为空

2.判断socket是否关闭 (使用isClosed())

3.手动关闭未关闭的socket

打包升级服务端后,客户端连接注册,问题解决


来自网络:

SOCKET CLOSE_WAIT状态的说明:
CLOSE_WAIT出现的原因: 就是某一方在网络连接断开后,对等方没有检测到这个错误(对方断开)而没有调用 closesocket,导致了这个状态的出现;
 
断开连接的时候: 
      当发起主动关闭的左边这方发送一个FIN过去后,右边被动关闭的这方要回应一个ACK,
 这个ACK是TCP回应的(同时TCP向上层应用程序提交一个ERROR,导致上面的SOCKET的send
 或者recv返回SOCKET_ERROR),而不是应用程序发送的,此时,被动关闭的一方就处于
 CLOSE_WAIT状态了。如果此时被动关闭的这一方不再继续调用closesocket,
 那么他就不会发送接下来的FIN,导致自己老是处于CLOSE_WAIT。只有被动关闭的这一方
 调用了closesocket,才会发送一个FIN给主动关闭的这一方,同时也使得自己的状态变迁
 为LAST_ACK,待接收到主动关闭方发送的ACK后,才会将SOCKET置为CLOSED。 
 
 首先我们知道,如果我们的Client程序处于CLOSE_WAIT状态的话,说明套接字是被动关闭的!
因为如果是Server端主动断掉当前连接的话,那么双方关闭这个TCP连接共需要四个packet:
       Server ---> FIN ---> Client
       Server <--- ACK <--- Client
    这时候Server端处于FIN_WAIT_2状态;而我们的程序处于CLOSE_WAIT状态。
       Server <--- FIN <--- Client
这时Client发送FIN给Server,Client就置为LAST_ACK状态。
        Server ---> ACK ---> Client
Server回应了ACK,那么Client的套接字才会真正置为CLOSED状态。


  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值