Достаточно ли достаточно вызова ServerSocket.close (), чтобы закрыть порт? - PullRequest
1 голос
/ 21 июля 2011

У меня есть некоторый код Java, который выглядит примерно так:

private void startServer() throws IOException {
        URLClassLoader classloader = null;

        System.out.println("Opening server socket for listening on " + PORT_NUMBER);
        try {
            server = new ServerSocket(PORT_NUMBER);
            server.setSoTimeout(10000);
            connected = true;
            System.out.println("Server is now listening on port " + PORT_NUMBER);
        } catch (IOException e) {
            System.err.println("Could not start server on port " + PORT_NUMBER);
            e.printStackTrace();
            connected = false;
        }

        while (connected) {

            // Incoming request handler socket.
            Socket socket = null;
            try {
                System.out.println("Waiting for client connection...");
                // Block waiting for an incoming connection.
                socket = server.accept();
                if (socket == null) continue;

... и так далее, и тому подобное.Когда я позже вызываю server.close () (я не получаю никакого другого поведения, если сначала вызываю socket.close ()), я не получаю никаких ошибок, но netstat показывает, что порт все еще прослушивается.Должен ли вызов ServerSocket.close () быть достаточным для освобождения порта в этой системе?

Я программирую для среды выполнения Java 1.4.2 microedition.Также стоит отметить, что у меня этот метод запущен в другом потоке, и я пытаюсь закрыть сокет от его родительского потока.

EDIT Вот строка из netstat,хотя я могу заверить вас, что он все еще прослушивается, так как, если я снова запускаю Xlet, я получаю исключение с этим номером порта.

tcp        0      0  *.2349                 *.*                    LISTEN

1 Ответ

5 голосов
/ 21 июля 2011

Есть несколько вещей, которые следует учитывать.Один из них описывается следующей цитатой из JavaDoc ServerSocket

public void setReuseAddress (boolean on), генерирует SocketException

Включить / отключить параметр сокета SO_REUSEADDR.Когда TCP-соединение закрыто, оно может оставаться в состоянии тайм-аута в течение некоторого времени после закрытия соединения (обычно это состояние TIME_WAIT или состояние ожидания 2MSL).Для приложений, использующих общеизвестный адрес сокета или порт, может быть невозможно привязать сокет к требуемому SocketAddress, если в состоянии тайм-аута имеется соединение с адресом или портом сокета.

Так чтоЭто нормально, что ОС все еще может показать, что что-то происходит после того, как вы close() сокет сервера.Но если вы собираетесь часто открывать / закрывать сокет сервера на одном и том же порту, вы можете столкнуться с проблемой.

...