SOCKET客户端与服务端长时间通信后,会连接不上服务端的问题,以及server端UDP丢包的问题
2014-04-12 23:23
651 查看
人生第一篇博客,希望能以一个好的开始,持之以恒下去!
这两天在做有关负载均衡的一个项目,期间在调试时遇到了一个问题:客户端与服务端依靠socket通信,但是长时间通信后,会发生客户端连接不上服务端的状况。而后查询了一些资料后,终于搞清楚问题的缘由了,在此和大家分享一下!
调试时的环境是:一个客户端,有多个服务端,那么客户端去连接哪个服务端是由负载均衡算法计算出来的,将众多server中负载最小的一个server的IP地址返回给客户端,而后client再去连接那台最优的server。
直接点说,问题的原因是客户端短时间内大批量的连接服务端后,系统没有多余的端口为后续的连接使用了。
当客户端与服务端通信时,系统会分配给客户端一个端口,但是在用户调用closesocket()之后,这些端口并不会close掉,而是处于TIME_WAIT状态。而TIME_WAIT状态的端口是无法被下面的连接使用的,而TIME_WAIT状态并不会一直持续下去,它会持续2个MSL时间,4分钟。这也就是客户端为什么在短时间内大批量的与服务端通信后,会连不上server端。
端口的TIME_WAIT状态,是TCP连接断开时肯定会出现的状态,是协议自我保护的一部分,我们当然可以调整TIME_WAIT等待的时间,但是我觉得,既然协议中这样设定了时间就一定有他的用意,根据一时的所需而去修改,肯定不理智,所以我就要减少建立连接的次数,以减少对端口的消耗。
同样的问题在server端也有可能会存在的。
补充另一个问题。
通过UDP在网络群组中做“心跳”功能时,吃时间运行后,出现本机只能收到本机发送的信息,而无法收到网络中其他的机器发送的信息。
工作的环境是:网络群组中的每一个server都会定时将自身的信息UDP广播出去,同时也在不断的接受信息。
出现问题的原因,我想了一下在于三点吧(领导人讲话,一般至少讲三点~~~)。第一,通过UDP广播出去的信息在网络中存在是有时间限制的;第二:server接受信息远比发送一条信息来的慢;第三:网络延时。系统会将从网络中收集到的信息存储一块内存中,然后,用户的recv()函数开始从内存中一条一条的取信息。但是由于取信息的速度“太慢”(相对而言),这就使得第n条信息,还没来得及被recv()到,就已经被删除了,因为它已经超过了存活时间。至于为什么还能收到本机发送的信息,而只是收不到网络中其他server发送的信息,并不是由于本机socket发送的信息不会丢失,同样的超过了存活时间,一样会被删除,只是由于网络延时的原因,内存中存活的本机信息,远多于网络中其他server发送的信息。
谢谢大家!我还在学习ing,欢迎大家批评指正!!!
这两天在做有关负载均衡的一个项目,期间在调试时遇到了一个问题:客户端与服务端依靠socket通信,但是长时间通信后,会发生客户端连接不上服务端的状况。而后查询了一些资料后,终于搞清楚问题的缘由了,在此和大家分享一下!
调试时的环境是:一个客户端,有多个服务端,那么客户端去连接哪个服务端是由负载均衡算法计算出来的,将众多server中负载最小的一个server的IP地址返回给客户端,而后client再去连接那台最优的server。
直接点说,问题的原因是客户端短时间内大批量的连接服务端后,系统没有多余的端口为后续的连接使用了。
当客户端与服务端通信时,系统会分配给客户端一个端口,但是在用户调用closesocket()之后,这些端口并不会close掉,而是处于TIME_WAIT状态。而TIME_WAIT状态的端口是无法被下面的连接使用的,而TIME_WAIT状态并不会一直持续下去,它会持续2个MSL时间,4分钟。这也就是客户端为什么在短时间内大批量的与服务端通信后,会连不上server端。
端口的TIME_WAIT状态,是TCP连接断开时肯定会出现的状态,是协议自我保护的一部分,我们当然可以调整TIME_WAIT等待的时间,但是我觉得,既然协议中这样设定了时间就一定有他的用意,根据一时的所需而去修改,肯定不理智,所以我就要减少建立连接的次数,以减少对端口的消耗。
同样的问题在server端也有可能会存在的。
补充另一个问题。
通过UDP在网络群组中做“心跳”功能时,吃时间运行后,出现本机只能收到本机发送的信息,而无法收到网络中其他的机器发送的信息。
工作的环境是:网络群组中的每一个server都会定时将自身的信息UDP广播出去,同时也在不断的接受信息。
出现问题的原因,我想了一下在于三点吧(领导人讲话,一般至少讲三点~~~)。第一,通过UDP广播出去的信息在网络中存在是有时间限制的;第二:server接受信息远比发送一条信息来的慢;第三:网络延时。系统会将从网络中收集到的信息存储一块内存中,然后,用户的recv()函数开始从内存中一条一条的取信息。但是由于取信息的速度“太慢”(相对而言),这就使得第n条信息,还没来得及被recv()到,就已经被删除了,因为它已经超过了存活时间。至于为什么还能收到本机发送的信息,而只是收不到网络中其他server发送的信息,并不是由于本机socket发送的信息不会丢失,同样的超过了存活时间,一样会被删除,只是由于网络延时的原因,内存中存活的本机信息,远多于网络中其他server发送的信息。
谢谢大家!我还在学习ing,欢迎大家批评指正!!!
相关文章推荐
- java客户端与服务端建立连接 线程 ServerSocket
- redis客户端在本地连接CentOS 7虚拟机的服务端时,为什么会报can't connect to redis-server 的错误??以及做主从复制的时候总是失败
- vc++/mfc socket网络通信多客户端和服务端安全问题,服务端只处理授权客户端
- 【转】UDP Socket编程-客户端和服务端双向通信
- android中ServerSocket和Socket通信连接问题
- 网络编程二(套接字Socket、客户端和服务端通信问题)
- ServerSocket多个客户端连接问题(原创,作者:cnzrs)
- C#客户端与Java程序使用socket连接并通信的兼容问题
- linux网络编程之用socket实现简单客户端和服务端的通信(基于UDP)
- Socket通信完整实例(心跳包,客户端断线重连,服务端超时断开客户端连接)
- Android开发——本机Tomcat搭建服务器,客户端socket网络连接不上问题以及D-LINK端口转发设置
- 当客户端socket关闭时,select模型的server端该如何完美的释放掉连接的socket? [问题点数:100分,结帖人guopo]
- 浅谈android Socket 通信及自建ServerSocket服务端常见问题
- Socket 通信原理(Android客户端和服务器以TCP&&UDP方式互通)(解决不可连的问题,解决方案在最后面)
- [Python]socket简易服务端客户端通信
- Socket实现手机客户端和PC机服务端通信
- TCP/UDP简易通信框架源码,支持轻松管理多个TCP服务端(客户端)、UDP客户端
- socket编程基于UDP的服务端客户端回声程序
- QT QUdpSocket的连接判断以及错误显示
- Python UDP客户端和服务端通信