套接字EADDRINUSE(地址已在使用中)

我正在做套接字编程。 我从下面的链接参考:

http://examples.javacodegeeks.com/android/core/socket-core/android-socket-example/

以下是关于我的问题的细节。 我已经为此ServerThread(我的项目需求)创build了Android库,并在testing应用程序中使用。

现在testing应用程序通过lib连接到这个过程。 第一次它工作得很好,但如果我closures并重新打开它与例外坠毁:

“EADDRINUSE(地址已被使用)”

还试过serverSocket.setReuseAddress(true)这个,但没有运气。

我的代码:

 public void run() { Socket socket = null; try { serverSocket = new ServerSocket(SERVER_PORT); serverSocket.setReuseAddress(true); } catch (IOException e) { Log.e(TAG, "exception1= " + e.getMessage()); } while (!Thread.currentThread().isInterrupted()) { try { socket = serverSocket.accept(); Log.d(TAG, "server Connected.......!!!!"); communicationThread = new CommunicationThread( socket); commThread = new Thread(communicationThread); commThread.start(); } catch (IOException e) { Log.e(TAG, "exception 2=" + e.getMessage()); } } } 

如果我调用serverSocket.close()我得到exception2作为服务器套接字closures。 通信线程与上一个链接中给出的相同。

Solutions Collecting From Web of "套接字EADDRINUSE(地址已在使用中)"

你必须在socket被绑定到端口之前调用setReuseAddress(true) 。 您之后调用它,因为您将端口传递给构造函数,该构造函数将立即绑定套接字。

试试这个:

 serverSocket = new ServerSocket(); // <-- create an unbound socket first serverSocket.setReuseAddress(true); serverSocket.bind(new InetSocketAddress(SERVER_PORT)); // <-- now bind it 

TCP(也可能是其他一些)套接字在closures后不能重复使用同一个端口。 这是为了防止现有连接的networking数据混乱。 您可以重写此行为,但是默认情况下是等待一段时间,然后才允许重新使用端口。

解决此问题的调用是服务器套接字上的setReuseAddress(true) 。 但是我不确定是否需要在第一个socket或第二个socket上调用,或者两者兼而有之。

编辑:

这里有一篇博客文章,描述了TCP套接字的TIME_WAIT状态及其存在的原因: http : //www.serverframework.com/asynchronousevents/2011/01/time-wait-and-its-design-implications-for-protocols-and-scalable -servers.html

虽然其他答案指出了setReuseAddress(true)的重要性, setReuseAddress(true)另一个可能出现的问题是构造ServerSocket两次,并使用相同的参数进行绑定。 例如,如果您调用两次问题的代码run()serverSocket将被分配给一个新的ServerSocket类实例,但是旧的仍然存在,直到垃圾收集。 现在用端口值作为参数构造等于绑定了ServerSocket对象,并且你将最终以两个ServerSocket绑定到同一个地址,这是被禁止的,因此是exception。 所以build立你的serverSocket与您select的端口只有一次!

尝试在run()方法之外创buildSocketServer的实例。

 protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState) try { // create a new instance of an unbound socket first serverSocket = new ServerSocket(); } catch (IOException e) { e.printStackTrace(); } }