import java.io.IOException;
import java.net.Socket;public class SocketTest {
public static void main(String[] args) {
for (int i = 0; i < 9999; ++i) {
try {
Socket socket = new Socket("127.0.0.1", 21);
socket.close();
} catch (IOException ioe) {
System.out.println("Error: " + i);
break;
} catch (Exception e) {
System.out.println("Other Exception: " + i);
return;
}
}
System.out.println("End");
}
}
不停的向某个端口发起连接,当达到一定数量的时候,就会连接不上,netstat -a 里面发现端口已经满了。我觉得是windows在哪个地方限制了连接端口的数量,或者socket端口释放得太慢。哪位大虾知道,Win2000上,这种问题该怎么解决?

解决方案 »

  1.   

    注:C++代码会有相同的表现,所以,会不会是windows设置的问题呢?
      

  2.   

    不可能改的, TCP端口数最多65535个.
      

  3.   

    怀疑是端口释放得太慢,就像多线程线程一样,for循环几乎是瞬间的,而连接和close则比较耗时,在for里面加个Thread.sleep(sometime)试试看
      

  4.   

    连接是有状态的, socket.close();之后是time_wait, 要达到中止状态确实需要时间
      

  5.   

    to TinyJimmy(Jimmy):
    但是,这个程序的结果,每当达到3900多次的时候,就会失败,肯定到不了4000次。请问,windows中是否还有其他的限制?to believefym(暮色,miss,迷失,miss) :我们这里有一个批量处理系统,要一次性的发送大量消息到服务器,而且,我们没有源代码,没办法改。所以,请问有没有其他的途径?to TinyJimmy(Jimmy): 请问,连接的状态是不是指listening,waiting等等?这个状态是由程序控制的还是windows控制的?有办法改变它的状态吗?
      

  6.   

    有限制, OS 没打开一个文件会占用一个 文件句炳,每打开一个 Socket 同样占用一个,而OS 最大文件句炳数是有限制的,服务器版的这个默认值会大些。具体修改注册表的什么地方就去问 Unix / C++ 的高手去。俺只在  DOS 年代的 autoexec.bat/config.sys 见过他。
      

  7.   

    windows时代会不会在注册表里呀?
      

  8.   

    to TinyJimmy(Jimmy):
    但是,这个程序的结果,每当达到3900多次的时候,就会失败,肯定到不了4000次。请问,windows中是否还有其他的限制?
    ======
    可能是操作系统打开句柄数或Buffer的限制, 也可能是并发线程总数的限制to TinyJimmy(Jimmy): 请问,连接的状态是不是指listening,waiting等等?这个状态是由程序控制的还是windows控制的?有办法改变它的状态吗?
    ======
    是的, 程序不能直接控制, 都在socket底层
      

  9.   

    就是说,我没有办法控制一个socket连接结束后的waiting时间了?通过操作系统设置,比如注册表,可以吗?
      

  10.   

    ======
    可能是操作系统打开句柄数或Buffer的限制, 也可能是并发线程总数的限制
    ====
    请问这种控制,在windows中可以进行设置吗?可以修改吗?
      

  11.   

    to: TinyJimmy(Jimmy) 请问这种控制,在windows中可以进行设置吗?可以修改吗?
      

  12.   

    这个问题其实跟java或者变成语言没有什么关系,呵呵,做服务器的人都会同样遇到问题的。呵呵。解决之道,加快处理时间(改代码调优),增加服务器(硬件投资)。
    如果调优很耗时也很艰巨,费用又紧张的话,还可以通过以下调整系统内核参数获得一定的改善。
    window nt系列
    在HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters下增加双字节值的注册表项:
    1)MaxUserPort 
       缺省是5000 (十进制)
       可以设置为最大65534 (十进制)
    2)TcpTimedWaitDelay
       缺省是240 (十进制)
       可以设置为最大30 (十进制)unix/linux
    echo 65536 > /proc/sys/fs/file-max 
    ulimit -n 65536
    此外在unix/linux的平台下,如果你选用的是FreeBSD的话,那就更加运气一下,可以通过
    echo net.inet.tcp.msl=2000 >> /etc/sysctl.conf 
    /etc/rc.d/sysctl restart
    来调整TIME_WAIT连接的超时,缺省为30000
      

  13.   

    谢谢  takecare(大厅),我试了一下,限制确实是打开了,但是我们的程序连接到1991此的时候还是会失败,不知道是否还有其他方面的限制?
      

  14.   

    另一个问题,windows有没有对程序打开文件数量的限制?如果有,该怎么修改呢?
      

  15.   

    呵呵,我主要是在linux上做tuning,顺带看了一下windows上的这方面的异常。
    而且个人感觉windows的文件系统确实做得比linux要好,我原来在做review的时候发现我们的程序员在一个发送线程中没有使用client socket的close,windows下使用还是没有大碍的;而同样的代码移植到linux下我们的应用连3分钟都撑不到。呵呵。
      

  16.   

    好像我参与过一个项目,也是服务器端,连续接收client端消息,也是到3900多就失败了,当时怀疑是缓冲区溢出,但后来发现不是,一直没有查到原因……
      

  17.   

    另外,我们的程序运行一段时间后,就会产生很多句柄(可能就是那个文件描述符),不停的增加,我怀疑是这个的问题。
    请问,您知道在windows2000中如何设置句柄或者是文件描述符(打开文件的数量限制)吗?
      

  18.   

    windows可以在“性能”标签下的
    “总数”中看到
    “句柄数” ——似乎足够大
    “线程数”
    “进程数”但是至于“句柄数”到底有多大的限制,我目前没有明确。
      

  19.   

    btw,你碰到没有足够的文件描述符可用吗?
    如果有的话,你把出错信息发给我看看。嘻嘻
      

  20.   

    我也曾经运行过你的客户端测试代码,我自己随便写了一个socketserver,是完全能够运行到底,不管那个循环多大,不过我可以试试看多线程建立连接会是什么结果?
      

  21.   

    作了将近两天测试,觉得我们的程序出了这里还有其他的问题,windows方面的限制,已经跟据takecare(大厅) 的建议,进行了修改,效果非常好。还剩一个问题,可能是我们的程序有一些内存泄露了。非常感谢大家的热心帮助。
      

  22.   

    嘿嘿,这是常见的too many open files问题.解决打开文件过多的问题
    --如果您遇到打开文件过多的异常,您面临的可能是操作系统资源缺乏问题。本文将讲述如何解决这个问题。
    参考
    http://dev2dev.bea.com.cn/techdoc/20050060103.html
      

  23.   

    对,就是  liu_you(滴水藏海)  给的连接。
    不过我居然在msdn里也没有找到微软关于最大文件句柄的描述,应该是我还没有找到,我相信微软的帮助里肯定有的。呵呵