Подтвердить что ты не робот

Как я могу прервать метод acceptSetServerSocket?

В моем основном потоке у меня есть цикл while(listening), который вызывает accept() на моем объекте ServerSocket, затем запускает новый клиентский поток и добавляет его в коллекцию при принятии нового клиента.

У меня также есть поток Admin, который я хочу использовать для выдачи команд, таких как "exit", что приведет к отключению всех клиентских потоков, закрытию себя и закрытию основного потока, путем включения ложь.

Однако вызов accept() в циклах цикла while(listening), и, похоже, нет никакого способа прервать его, поэтому условие while не может быть снова проверено, и программа не может выйти!

Есть ли лучший способ сделать это? Или каким-то образом прервать метод блокировки?

4b9b3361

Ответ 2

Установите тайм-аут на accept(), тогда вызов будет блокировать блокировку по истечении указанного времени:

http://docs.oracle.com/javase/7/docs/api/java/net/SocketOptions.html#SO_TIMEOUT

Установите тайм-аут блокировки операций сокета:      ServerSocket.accept();      SocketInputStream.read();      DatagramSocket.receive();

Параметр должен быть установлен перед вводом в действие блокировки. Если истечет время ожидания и операция будет продолжать блокироваться, возникает java.io.InterruptedIOException. В этом случае сокет не закрывается.

Ответ 4

Причина serversocket.close() вызывает исключение , потому что у вас есть выходной поток или входной поток, подключенный к этому сокету. Вы можете очень хорошо избежать этого исключения безопасно, сначала закрыв входные и выходные потоки. а затем попробуйте закрыть сервер. Напишите простой метод

void closeServer() throws IOException {
  try {
    if(outputstream!=null)
      outputstream.close();
    if(inputstream!=null)
      inputstream.close();
  } catch (IOException e1) {
    e1.printStackTrace();
  }
  if(!serversock.isClosed())
    serversock.close();
  }
}

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

Ответ 5

Вы можете просто создать сокет "void" для break serversocket.accept()

Серверная сторона

private static final byte END_WAITING = 66;
private static final byte CONNECT_REQUEST = 1;

while (true) {
      Socket clientSock = serverSocket.accept();
      int code = clientSock.getInputStream().read();
      if (code == END_WAITING
           /*&& clientSock.getInetAddress().getHostAddress().equals(myIp)*/) {
             // End waiting clients code detected
             break;
       } else if (code == CONNECT_REQUEST) { // other action
           // ...
       }
  }

Метод для прерывания цикла сервера

void acceptClients() {
     try {
          Socket s = new Socket(myIp, PORT);
          s.getOutputStream().write(END_WAITING);
          s.getOutputStream().flush();
          s.close();
     } catch (IOException e) {
     }
}

Ответ 6

Еще одна вещь, которую вы можете попробовать, которая является более чистой, - проверить флаг в цикле принятия, а затем, когда ваш поток администратора хочет уничтожить блокировку потока при принятии, установите флаг (сделайте его потокобезопасным), а затем сделайте подключение клиентского сокета к гнезду для прослушивания. Принятие прекратит блокировку и вернет новый сокет. Вы можете проработать какую-то простую информацию о протоколе, сообщающую прослушивающему потоку, чтобы выйти из потока чисто. Затем закройте сокет на стороне клиента. Никаких исключений, гораздо более чистых.