论坛首页 Java企业应用论坛

系统运行一段时间后,客户端不能连接上服务器(有SOCKET开发经验的欢迎一起讨论)

浏览 8691 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2007-12-28  
情况是这样的,我们的一台服务器连接比较多。他由两个部分组成,WEB部分和应用服务。这台服务器存在以下几种连接

1)和另外一个服务器的长连接
2)和几百台设备的短连接(服务器需要频繁访问这些设备)
3)从这台服务器的WEB到应用的短连接(需要应用转发到设备成功后再原路返回)
4)和客户端的长连接(把设备信息发送给客户端查看)

服务器刚启动时间后运行很正常,大概过了一个星期后,开始逐渐不能连接上这台服务器。
=========================================================================
这个可能是连接的相关资源耗尽了,NETSTAT一下会发现一些TIME_WAIT,还有少数的几个FIN_WAIT_1,至于具体什么耗尽了,我也说不上来。因为这种情况在测试环境中比较难模拟,还请各位有类似开发经验的能多多发表自己的意见,谢谢!
   发表时间:2007-12-28  
一般来说,一台机器对外连接数是有限的,象你这种情况就是连接没有释放导致的。你可以在建立连接时做计数器,来统计哪一种类型的连接占用的时间长,没有释放,应该很容易找到问题所在的,就跟连接池的处理是一个道理,你也在你的系统中建立一个类似于连接池或对象池的概念,不再由应用进行直接连接,把连接统一管理。
0 请登录后投票
   发表时间:2007-12-28  
这个是无可用端口的问题。

对外连接时,一般使用系统分配的端口。即使关闭socket,这个socket还会被time_wait一段时间(似乎是1~2分钟左右)。根据系统不同,提供给系统自动分配的端口也是有限的(windows下仅有1000左右)。所以只要在2分钟内有过上千个连接,那么可用端口就会被消耗干净,这时候建立socket就会失败。

解决方法:不要让系统自动分配端口,而在创建socket的时候指定端口,这样可以跳出只能用1000个左右端口的限制。另外还要尽量分散连接建立的时间,不要出现短期内有高连接数的峰值。
0 请登录后投票
   发表时间:2007-12-28  
timerri 写道
这个是无可用端口的问题。

对外连接时,一般使用系统分配的端口。即使关闭socket,这个socket还会被time_wait一段时间(似乎是1~2分钟左右)。根据系统不同,提供给系统自动分配的端口也是有限的(windows下仅有1000左右)。所以只要在2分钟内有过上千个连接,那么可用端口就会被消耗干净,这时候建立socket就会失败。

解决方法:不要让系统自动分配端口,而在创建socket的时候指定端口,这样可以跳出只能用1000个左右端口的限制。另外还要尽量分散连接建立的时间,不要出现短期内有高连接数的峰值。


LINUX和UNIX下一般系统自动分配的端口会有多少?
我感觉你说的比较正确,连接我可以确定都关闭了,如果不关闭也撑不到一个星期,我们系统的交易压力还是蛮大的。我先按照你的做法测试下看看。
0 请登录后投票
   发表时间:2007-12-29  
我也遇到这样类似的问题。在连接是出现了no buffer space available异常。
我的连接是有两种方式:1是建立套节字socket为客户端,向下面的设备发送消息,并接受返回的消息。2是通过建立ftp连接的方式将消息以ftp方式上传文件到下面的设备并同时下载返回文件。
在系统运行2天后出现了上面所说的异常,我的代码里面的tcp连接都有过关闭连接操作。不知道是什么原因造成的。
我的系统是win2k ser ,装了瑞星杀毒软件有防火墙。
0 请登录后投票
   发表时间:2007-12-30  
看了几篇文章传说socket.setReuseAddress(true)可以让TIME_WAIT的状态的可以重用。非常可惜的是即便是使用了这个参数也没用,后来看到好像是JDK的一个BUG,见http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6213296

0 请登录后投票
   发表时间:2007-12-31  
    检查一下网络设置是否有问题。 子网掩码是否设置过大。 arp -a看看mac表的状态。

还有有时unix会启动routed进程。看看路由表是否有问题。
0 请登录后投票
   发表时间:2008-01-01  
rainshow 写道
看了几篇文章传说socket.setReuseAddress(true)可以让TIME_WAIT的状态的可以重用。非常可惜的是即便是使用了这个参数也没用,后来看到好像是JDK的一个BUG,见http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6213296




转一下
其实这个问题在Richard Stevens的《Unix网络编程指南》卷一里有很详细的
解答(中文版P166-168页)。这里我只是写几个基本的例子来验证这个问题。
    首先声明一个问题:当两个socket的address和port相冲突,而你又想重用地
址和端口,则旧的socket和新的socket都要已经被设置了SO_REUSEADDR特性,只
有两者之一有这个特性还是有问题的。
    SO_REUSEADDR可以用在以下四种情况下。
    (摘自《Unix网络编程》卷一,即UNPv1)
    1、当有一个有相同本地地址和端口的socket1处于TIME_WAIT状态时,而你启
动的程序的socket2要占用该地址和端口,你的程序就要用到该选项。
    2、SO_REUSEADDR允许同一port上启动同一服务器的多个实例(多个进程)。但
每个实例绑定的IP地址是不能相同的。在有多块网卡或用IP Alias技术的机器可
以测试这种情况。
    3、SO_REUSEADDR允许单个进程绑定相同的端口到多个socket上,但每个soc
ket绑定的ip地址不同。这和2很相似,区别请看UNPv1。
    4、SO_REUSEADDR允许完全相同的地址和端口的重复绑定。但这只用于UDP的
多播,不用于TCP。

0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics