2016-04-06 3 views
2

Я создаю приложение чата с Java-сокетами и получаю SocketException: socket closed при закрытии сервера. Я получаю сообщение об ошибке , даже если я никогда не пытаюсь подключиться к клиентам. - только остановка сервера будет иметь это закрытое исключение сокета.SocketException: socket closed

Я знаю, что означает ошибка, я пытаюсь получить доступ к сокету, когда он уже закрыт, но я не могу понять, почему это произойдет.

public ServerSocket server_socket; 
new ConnectionThread(server_back_end); 

class ConnectionThread extends Thread implements Runnable, Serializable 
{ 
    public ServerBackEnd server_back_end; 

    public ConnectionThread(ServerBackEnd server_back_end) /*constructor*/ 
    { 
     this.server_back_end = server_back_end; 
     start(); 
    } 

    @Override 
    public void run() 
    { 
     try 
     { 
      server_back_end.server_socket = new ServerSocket(8080); 
      server_back_end.server_front_end.display("<<SERVER STARTED>>"); 

      while (server_back_end.running) 
       add_incoming_clients(); 
     } 
     catch (Exception e) 
     { 
      e.printStackTrace(); //this gets thrown when I stop server 
     } 
    }//end run() 

Я думаю, что проблема в add_incoming_clients(), потому что, когда я закомментировать вызов, он не бросает ошибку. Даже если я не дело с любыми клиентами, что-то происходит в accept() метода:

public void add_incoming_clients() throws IOException, ClassNotFoundException 
    { 
     Socket client_socket = server_back_end.server_socket.accept(); //line 172 

     ClientInfo new_client = new ClientInfo(
       new ObjectOutputStream(client_socket.getOutputStream()), 
       new ObjectInputStream(client_socket.getInputStream())); 
    //... 
    //... 
    } 

Вот код, когда я остановить сервер ::

public void stop() 
    { 
     if (running) 
      try 
      { 
       running = false; 
       server_socket.close(); 
       server_front_end.display("<<SERVER TERMINATED>>"); 
      } 
      catch (IOException e) 
      { 
       System.out.println("stop server exception, is not the problem"); 
      } 
    }//end stop() 

Может кто-нибудь объяснить, что я должен сделать, чтобы правильно закрыть его без исключения? Здесь ошибка (строка 172 является виновником, кажется, но я не понимаю, почему)

java.net.SocketException: socket closed 
    at java.net.DualStackPlainSocketImpl.accept0(Native Method) 
    at java.net.DualStackPlainSocketImpl.socketAccept(DualStackPlainSocketImpl.java:131) 
    at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:409) 
    at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:199) 
    at java.net.ServerSocket.implAccept(ServerSocket.java:545) 
    at java.net.ServerSocket.accept(ServerSocket.java:513) 
    at ConnectionThread.add_incoming_clients(ServerBackEnd.java:172) 
    at ConnectionThread.run(ServerBackEnd.java:159) 

ответ

2

Это исключение является вашим другом. Он освобождает поток, который ждет ServerSocket.accept(), и правильная обработка позволит вам очистить все, что нужно очистить, прежде чем полностью закрыть ... Вам нужно относиться к нему как к другу :)

+0

Oh! Я не знал! Я пытался запрограммировать как можно более правильно, и думал, что это исключение не было «другом». Имеет смысл, почему теперь вы объяснили это. Спасибо!! – user3487243

+0

@ user3487243 Добро пожаловать. Кстати, вы можете изменить свой код, чтобы поймать (SocketException ex), чтобы поймать это против других видов Исключений. Он также служит для «документирования кода», что происходит – ControlAltDel

+0

Хороший улов. С точки зрения запуска программы это не будет слишком большой разницей, которую я предполагаю? Это просто для явного обнаружения конкретного исключения – user3487243

1

Looking на трассе и в коде. Когда вы останавливаете(), первое, что вам нужно сделать, - это уведомить Thread Connection о том, чтобы остановить его действия, а затем продолжить с помощью метода stop, как только вы узнаете, что поток соединения мертв ,

Может случиться так, что стоп-сигнал закроет розетку, когда используется резьба соединения. Вы можете видеть, что на трассе

+0

, как я могу уведомить тему подключения? Я думал, что смогу только закрыть розетку и быть в пути? – user3487243

+0

Существует несколько механизмов для взаимодействия между потоками. Вы можете поделиться флагом переменной и остановить поток, если этот флаг станет истинным или ложным (и отредактируйте этот флаг в функции stop()). Вот что они предлагают здесь: http://stackoverflow.com/questions/671049/how-do-you-kill-a-thread-in-java – rdavb

+0

А, да. Я использую для этого переменную boolean. Спасибо за напоминание! – user3487243

Смежные вопросы