java.nio.channels.ServerSocketChannel не закрывается должным образом

1

У меня есть java.nio.channels.ServerSocketChannel который я инициализировал следующим образом:

while(true)
{
    ServerSocketChannel channel = ServerSocketChannel.open();
    InetSocketAddress serverSocket = new InetSocketAddress(host,port);
    channel.bind(serverSocket);
    SocketChannel ch = channel.accept();

    // Later on when I have read off data from a client, I want to shut this 
    // connection down and restart listening.
    channel.socket().close(); //Just trying to close the associated socket 
    // too because earlier approaches failed
    channel.close();
}               

Когда я отправляю первое сообщение от клиента, он успешно доставляется на сервер, и клиентская программа завершается. Тогда начинаются неприятности. Когда я снова инициализирую клиента и пытаюсь установить в том же порту и адресе сервера, как и в первый раз, я получаю

java.net.BindException: адрес уже используется: connect

исключение, хотя я закрыл связанный канал/сокет. Я обновляю объекты ServerSocketChannel и InetSocketAddress потому что, поскольку мой клиентский экземпляр должен отключиться после записи, я должен отключить этот канал, и поскольку я не могу повторно использовать канал после его закрытия, я должен каждый раз создавать новый объект. Моя теория с тех пор, как ссылка на channel переназначается каждый раз, осиротевший объект становится GC-мясом, но поскольку метод close(), по-видимому, не работает должным образом, канал все еще жив, и пока GC не собирает его, мой порт будет запутан. Тем не менее я попытался сохранить инициализацию объектов ServerSocketChannel и InetSocketAddress до цикла while, но это не помогло, и такое же исключение произошло после первой записи, как и раньше.

 ServerSocketChannel channel = ServerSocketChannel.open();
 InetSocketAddress serverSocket = new InetSocketAddress(host,port);
 channel.bind(serverSocket);

 while (true)
 {
    SocketChannel ch = channel.accept();
    //read from a client
 }              

Для ясности, вот как я подключаюсь от клиента:

        SocketChannel ch=SocketChannel.open();
        ch.bind(new InetSocketAddress("localhost", 8077));
        InetSocketAddress address=new InetSocketAddress("localhost",8079);
                    //the address and port of the server
        System.out.print(ch.connect(address));
        ByteBuffer buf=ByteBuffer.allocate(48);
        buf.clear();
        buf.put("Hellooooooooooooooooooooooooo".getBytes());
        buf.flip();
        while(buf.hasRemaining()) {
            ch.write(buf);
        }
        ch.close();
Теги:
sockets
garbage-collection
nio

2 ответа

3
Лучший ответ

Похоже, вы запутываете клиента и сервер. Обычно сервер запускается только один раз и bind к порту s. Как правило, нет необходимости close что-либо, поскольку порт освобождается при выходе из программы. Очевидно, вы должны закрыть Socket полученный ServerSocket.accept(), но это другая история.

Я думаю, вы запутались в своих именах переменных (как это случилось со мной, когда я начал с этого). Попытайтесь назвать все по своему типу, здесь венгерский действительно помог мне.


Код, который я написал для тестирования, длинный, глупый и скучный. Но, похоже, это работает.

  • 0
    Это определенно, казалось, имело место в ванильных розетках. Однако в нио вещи кажутся странными. Я постараюсь уделять больше внимания именам переменных.
  • 1
    Я не уверен, знал ли я, о чем говорю ... Поэтому я попробовал это сделать, и связывание и закрытие ServerSocketChannel похоже, работает. Даже некоторое общение делает. Я свяжу это, когда немного отполирую.
Показать ещё 13 комментариев
-4

сделайте ch.close(), а также GC-клиент.

  • 0
    Вы имеете в виду помимо channel.close () и channel.socket (). Close ()?
  • 0
    да правильно .. попробуйте это ..
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню