Android在什么时候可以自由端口



我有一个子活动,它创建一个异步任务,打开Java ServerSocket并在该服务器端口上调用accept()。

现在,在这个Activity的onStop()方法中,我调用了cancel()异步任务。在我的异步类中,在onPostExecute()和onCancelled()方法中,我关闭serverSocket(以及可能已打开的任何其他dataStreams或Sockets)。

我的所有代码都能正常运行。通过调试,我知道如果我:

  1. 线性运行应用程序,直到serverSocket开始接受()连接
  2. 点击后退按钮,关闭子活动并调用其onStop()方法,然后取消有问题的异步任务并在serverSocket上调用close()
  3. 再次运行子活动,创建新的异步线程,代码一直运行到我在与第一个端口相同的端口上创建serverSocket。但是,它抛出一个IO异常,并表示端口已在使用中
  4. 无论我等待多长时间重新启动此子活动,都会触发IO异常,声称端口已占用。然而,做这样的事情:

    重新启动设备

    重新安装应用程序

    完全关闭应用程序(而不是仅从其父活动重新启动子活动)

似乎要释放端口。

Android究竟是如何刷新/释放您使用过的端口的?有什么办法可以用程序调用这些端口的刷新吗?

在出现明显的问题之前,我使用的是P2P和java套接字,所以是的,我确实想使用到套接字的直接连接,并在静态本地端口上直接接受等等。

编辑:格式化

编辑2:更改后

serverSocket = new ServerSocket(portNumber);
socket = serverSocket.accept();

收件人:

serverSocket = new ServerSocket();
serverSocket.setReuseAddress(true);
serverSocket.bind(new InetSocketAddress("192.168.49.1", 8000));
socket = serverSocket.accept();

我现在得到一个java.net.BindException:绑定失败:EADDNOTAVAIL(无法分配请求的地址)异常。(这只发生在第一组条件之后。应用程序的第一次运行仍然像以前一样正常运行)。

编辑3:如果我找到了一种正确的方法,我会在编辑中发布它,但现在(调试)我只会走快速而肮脏的路线,每当用户按下后退按钮并将应用程序重新启动到主活动时,我就会完全杀死应用程序。这似乎消除了端口绑定。

几分钟后,仍在网络中的请求不会在同一个quad(源ip、源端口、目标ip、目标端口)上发送信息。这是TCP套接字在所有操作系统(在Windows、Linux、*BSD等中)中的一个常见特性。您可以通过在套接字上指定SO_REUSEADDR选项来关闭它,该选项将告诉操作系统在关闭端口后不要保留端口

这里有一个很好的解释SO_REUSEADDR的作用:SO_REUSEADD(setsockopt选项)-Linux的含义是什么?

最新更新