Address already in use: JVM

xiaoxiao2026-05-24  0

在网络编程中,特别是在短时间内new的网络连接太多,经常出现java.net.BindException: Address already in use: JVM_Bind的异常,网络有很多介绍此异常的,通常都是在说是要使用的端口被别的程序已经使用,但有时并不是这个原因,通过仔细查找,找到一些很好的资料,在此将其一一记录下来。**********************************************************************************文章一  短时间内new socket操作过多  而socket.close()操作并不能立即释放绑定的端口  而是把端口设置为TIME_WAIT状态  过段时间(默认240s)才释放(用netstat -na可以看到)  最后系统资源耗尽  (windows上是耗尽了pool of ephemeral ports 这段区间在1024-5000之间)Socket FAQ:  Remember that TCP guarantees all data transmitted will be delivered,if at all possible. When you close a socket, the server goes into aTIME_WAIT state, just to be really really sure that all the data hasgone through. When a socket is closed, both sides agree by sendingmessages to each other that they will send no more data. This, itseemed to me was good enough, and after the handshaking is done, thesocket should be closed. The problem is two-fold. First, there is noway to be sure that the last ack was communicated successfully.Second, there may be "wandering duplicates" left on the net that mustbe dealt with if they are delivered.Andrew Gierth (andrew@erlenstar.demon.co.uk) helped to explain theclosing sequence in the following usenet posting:Assume that a connection is in ESTABLISHED state, and the client isabout to do an orderly release. The client's sequence no. is Sc, andthe server's is Ss. Client Server====== ======ESTABLISHED ESTABLISHED(client closes)ESTABLISHED ESTABLISHEDRESOLUTIONWarning Serious problems might occur if you modify the registry incorrectly by using Registry Editor or by using another method. These problems might require that you reinstall your operating system. Microsoft cannot guarantee that these problems can be solved. Modify the registry at your own risk.The default maximum number of ephemeral TCP ports is 5000 in the products that are included in the 'Applies to' section. A new parameter has been added in these products. To increase the maximum number of ephemeral ports, follow these steps: 1.Start Registry Editor.2.Locate the following subkey in the registry, and then click Parameters: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters3.On the Edit menu, click New, and then add the following registry entry: Value Name: MaxUserPortValue Type: DWORDValue data: 65534Valid Range: 5000-65534 (decimal)Default: 0x1388 (5000 decimal)Description: This parameter controls the maximum port number that is used when a program requests any available user port from the system. Typically , ephemeral (short-lived) ports are allocated between the values of 1024 and 5000 inclusive.4.Quit Registry Editor.Note An additional TCPTimedWaitDelay registry parameter determines how long a closed port waits until the closed port can be reused.原文连接:http://blog.chinaunix.net/u/29553/showart_450701.html**********************************************************************************文章二java.net.BindException: Address already in use: connect的问题大概原因是短时间内new socket操作很多,而socket.close()操作并不能立即释放绑定的端口,而是把端口设置为TIME_WAIT状态,过段时间(默认240s)才释放,(用netstat -na可以看到),最后系统资源耗尽(windows上是耗尽了pool of ephemeral ports ,这段区间在1024-5000之间; )避免出现这一问题的方法有两个,一个是调高你的web服务器的最大连接线程数,调到1024,2048都还凑合,以resin为例,修改resin.conf中的thread-pool.thread_max,如果你采用apache连resin的架构,别忘了再调整apache;另一个是修改运行web服务器的机器的操作系统网络配置,把time wait的时间调低一些,比如30s。在red hat上,查看有关的选项,[xxx@xxx~]$ /sbin/sysctl -a|grep net.ipv4.tcp_twnet.ipv4.tcp_tw_reuse = 0net.ipv4.tcp_tw_recycle = 0[xxx@xxx~]$vi /etc/sysctl,修改net.ipv4.tcp_tw_reuse = 1net.ipv4.tcp_tw_recycle = 1[xxx@xxx~]$sysctl -p,使内核参数生效socket-faq中的这一段讲time_wait的,摘录如下:2.7. Please explain the TIME_WAIT state.Remember that TCP guarantees all data transmitted will be delivered,if at all possible. When you close a socket, the server goes into aTIME_WAIT state, just to be really really sure that all the data hasgone through. When a socket is closed, both sides agree by sendingmessages to each other that they will send no more data. This, itseemed to me was good enough, and after the handshaking is done, thesocket should be closed. The problem is two-fold. First, there is noway to be sure that the last ack was communicated successfully.Second, there may be "wandering duplicates" left on the net that mustbe dealt with if they are delivered.Andrew Gierth (andrew@erlenstar.demon.co.uk) helped to explain theclosing sequence in the following usenet posting:Assume that a connection is in ESTABLISHED state, and the client isabout to do an orderly release. The client's sequence no. is Sc, andthe server's is Ss. Client Server====== ======ESTABLISHED ESTABLISHED(client closes)ESTABLISHED ESTABLISHED------->>FIN_WAIT_1>TIME_WAIT CLOSED(2*msl elapses...)CLOSEDNote: the +1 on the sequence numbers is because the FIN counts as onebyte of data. (The above diagram is equivalent to fig. 13 from RFC793).Now consider what happens if the last of those packets is dropped inthe network. The client has done with the connection; it has no moredata or control info to send, and never will have. But the server doesnot know whether the client received all the data correctly; that'swhat the last ACK segment is for. Now the server may or may not carewhether the client got the data, but that is not an issue for TCP; TCPis a reliable rotocol, and must distinguish between an orderlyconnection close where all data is transferred, and a connection abortwhere data may or may not have been lost.So, if that last packet is dropped, the server will retransmit it (itis, after all, an unacknowledged segment) and will expect to see asuitable ACK segment in reply. If the client went straight to CLOSED,the only possible response to that retransmit would be a RST, whichwould indicate to the server that data had been lost, when in fact ithad not been.(Bear in mind that the server's FIN segment may, additionally, containdata.)DISCLAIMER: This is my interpretation of the RFCs (I have read all theTCP-related ones I could find), but I have not attempted to examineimplementation source code or trace actual connections in order toverify it. I am satisfied that the logic is correct, though.More commentarty from Vic:The second issue was addressed by Richard Stevens (rstevens@noao.edu,author of "Unix Network Programming", see ``1.5 Where can I get sourcecode for the book [book title]?''). I have put together quotes fromsome of his postings and email which explain this. I have broughttogether paragraphs from different postings, and have made as fewchanges as possible.From Richard Stevens (rstevens@noao.edu):If the duration of the TIME_WAIT state were just to handle TCP's full-duplex close, then the time would be much smaller, and it would besome function of the current RTO (retransmission timeout), not the MSL(the packet lifetime).A couple of points about the TIME_WAIT state.o The end that sends the first FIN goes into the TIME_WAIT state,because that is the end that sends the final ACK. If the otherend's FIN is lost, or if the final ACK is lost, having the end thatsends the first FIN maintain state about the connection guaranteesthat it has enough information to retransmit the final ACK.o Realize that TCP sequence numbers wrap around after 2**32 byteshave been transferred. Assume a connection between A.1500 (host A,port 1500) and B.2000. During the connection one segment is lostand retransmitted. But the segment is not really lost, it is heldby some intermediate router and then re-injected into the network.(This is called a "wandering duplicate".) But in the time betweenthe packet being lost & retransmitted, and then reappearing, theconnection is closed (without any problems) and then anotherconnection is established between the same host, same port (thatis, A.1500 and B.2000; this is called another "incarnation" of theconnection). But the sequence numbers chosen for the newincarnation just happen to overlap with the sequence number of thewandering duplicate that is about to reappear. (This is indeedpossible, given the way sequence numbers are chosen for TCPconnections.) Bingo, you are about to deliver the data from thewandering duplicate (the previous incarnation of the connection) tothe new incarnation of the connection. To avoid this, you do notallow the same incarnation of the connection to be reestablisheduntil the TIME_WAIT state terminates.Even the TIME_WAIT state doesn't complete solve the second problem,given what is called TIME_WAIT assassination. RFC 1337 has moredetails.o The reason that the duration of the TIME_WAIT state is 2*MSL isthat the maximum amount of time a packet can wander around anetwork is assumed to be MSL seconds. The factor of 2 is for theround-trip. The recommended value for MSL is 120 seconds, butBerkeley-derived implementations normally use 30 seconds instead.This means a TIME_WAIT delay between 1 and 4 minutes. Solaris 2.xdoes indeed use the recommended MSL of 120 seconds.A wandering duplicate is a packet that appeared to be lost and wasretransmitted. But it wasn't really lost ... some router hadproblems, held on to the packet for a while (order of seconds, couldbe a minute if the TTL is large enough) and then re-injects the packetback into the network. But by the time it reappears, the applicationthat sent it originally has already retransmitted the data containedin that packet.Because of these potential problems with TIME_WAIT assassinations, oneshould not avoid the TIME_WAIT state by setting the SO_LINGER optionto send an RST instead of the normal TCP connection termination(FIN/ACK/FIN/ACK). The TIME_WAIT state is there for a reason; it'syour friend and it's there to help you :-)I have a long discussion of just this topic in my just-released"TCP/IP Illustrated, Volume 3". The TIME_WAIT state is indeed, one ofthe most misunderstood features of TCP.I'm currently rewriting "Unix Network Programming" (see ``1.5 Wherecan I get source code for the book [book title]?''). and will includelots more on this topic, as it is often confusing and misunderstood.An additional note from Andrew:Closing a socket: if SO_LINGER has not been called on a socket, thenclose() is not supposed to discard data. This is true on SVR4.2 (and,apparently, on all non-SVR4 systems) but apparently not on SVR4; theuse of either shutdown() or SO_LINGER seems to be required toguarantee delivery of all data.原文连接:http://hi.baidu.com/w_ge/blog/item/105877c6a361df1b9c163d21.html************************************************************************文章三当您尝试从 TCP 端口大于 5000 连接收到错误 ' WSAENOBUFS (10055) '症状如果您尝试建立 TCP 连接从端口是大于 5000, 本地计算机响应并以下 WSAENOBUFS (10055) 错误信息: 因为系统缺乏足够缓冲区空间或者因为队列已满无法执行套接字上操作。 解决方案要点 此部分, 方法或任务包含步骤告诉您如何修改注册表。 但是, 如果修改注册表错误可能发生严重问题。 因此, 确保仔细执行这些步骤。 用于添加保护之前, 修改备份注册表。 然后, 在发生问题时还原注册表。 有关如何备份和还原注册表, 请单击下列文章编号以查看 Microsoft 知识库中相应: 默认最大数量的短暂 TCP 端口为 5000 ' 适用于 ' 部分中包含产品中。 这些产品中已添加新参数。 要增加最大值是短暂端口, 请按照下列步骤操作: 1.启动注册表编辑器。 2.注册表, 中找到以下子项, 然后单击 参数 : HKEY _ LOCAL _ MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters3.在 编辑 菜单, 单击 新建 , 然后添加以下注册表项: MaxUserPort 值名称:值类型: DWORD值数据: 65534有效范围: 5000 - 65534 (十进制)默认: 0x1388 5000 (十进制)说明: 此参数控制程序从系统请求任何可用用户端口时所用最大端口数。 通常, 1024 的值和含 5000 之间分配临时 (短期) 端口。 4.退出注册表编辑器, 并重新启动计算机。 注意 一个附加 TCPTimedWaitDelay 注册表参数决定多久关闭端口等待可以重用关闭端口。 对应英文原文为:SYMPTOMSIf you try to set up TCP connections from ports that are greater than 5000, the local computer responds with the following WSAENOBUFS (10055) error message: An operation on a socket could not be performed because the system lacked sufficient buffer space or because a queue was full. RESOLUTIONImportant This section, method, or task contains steps that tell you how to modify the registry. However, serious problems might occur if you modify the registry incorrectly. Therefore, make sure that you follow these steps carefully. For added protection, back up the registry before you modify it. Then, you can restore the registry if a problem occurs. For more information about how to back up and restore the registry, click the following article number to view the article in the Microsoft Knowledge Base: 322756(http://support.microsoft.com/kb/322756/) How to back up and restore the registry in WindowsThe default maximum number of ephemeral TCP ports is 5000 in the products that are included in the 'Applies to' section. A new parameter has been added in these products. To increase the maximum number of ephemeral ports, follow these steps: 1.Start Registry Editor. 2.Locate the following subkey in the registry, and then click Parameters: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters3.On the Edit menu, click New, and then add the following registry entry: Value Name: MaxUserPortValue Type: DWORDValue data: 65534Valid Range: 5000-65534 (decimal)Default: 0x1388 (5000 decimal)Description: This parameter controls the maximum port number that is used when a program requests any available user port from the system. Typically , ephemeral (short-lived) ports are allocated between the values of 1024 and 5000 inclusive. 4.Exit Registry Editor, and then restart the computer. Note An additional TCPTimedWaitDelay registry parameter determines how long a closed port waits until the closed port can be reused.原文连接:http://support.microsoft.com/kb/q196271/上文来自ChinaUnix博客,如果查看原文请点:http://bbs.chinaunix.net/viewthread.php?tid=1186157

 

********************************************************************************** 附

java.net.BindException: Address already in use: JVM_Bind

    at java.net.PlainSocketImpl.socketBind(Native Method)

    at java.net.PlainSocketImpl.bind(Unknown Source)

    at java.net.ServerSocket.bind(Unknown Source)

    at java.net.ServerSocket.<init>(Unknown Source)

    at java.net.ServerSocket.<init>(Unknown Source)

    at mypackage.WebServer.startServer(WebServer.java:13)

    at mypackage.WebServer.main(WebServer.java:33)

这是我学JavaWeb遇到的第一个错误,解决花了一些时间。看到错误不要害怕,因为解决错误的同时,正是我们经验值增长也在增长的哦

这个是我在使用Socket和多线程实现一个JavaWeb服务器时遇到的

Address already in use 这句话是地址已经使用

这个是遇到这个问题的可能情况

I.就是当前端口已经有别的程序在占用着,所以要么把占用这个端口的程序关闭,要么重新换一个端口

II.端口号被占用,如果你有装oracle的话,有可能是oracle使用了8080端口,oracle安装后并且如果启动了OracleHttp服务会占用8080端口

III.我认为很可能是多启动了几次TOMCAT,ECLIPSE下重复启动TOMCAT就会出现这个问题,你去调查一下看看是否是这个原因.

IV.如果不是windows操作系统,那么80端口已经被占用.如果是windows操作系统.请检查是否装有IIS.

查找问题原因:我的机子还没有装Oracle,并且使用的是Windows操作系统,装了IIS了,使用的是80端口,但我这个程序是用的8080端口,排除了II、IV。I说的笼统了点,我的问题是III多启动了几次TOMCAT,ECLIPSE下重复启动TOMCAT就会出现这个问题

解决方法:

1.把myeclipse关掉后台的javax.exe进程杀掉。然后重新启动myeclipse就可以了

2. 把tomcat\conf文件夹里面的server.xml的端口换成其它未占用的80端口 如:8088、8089等等

建议出现上述情况使用第一种方法。

上文来自博客,如果查看原文请点:http://blog.csdn.net/zhulin902/archive/2008/12/17/3538540.aspx

 

转载请注明原文地址: https://www.6miu.com/read-5049289.html

最新回复(0)