не удается закрыть сокет сервера - PullRequest
1 голос
/ 30 ноября 2011

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

Старая версия запускала отдельный поток для сервера, выполняла цикл while, который останавливался при отправке сообщения о остановке, а затем закрывал сокет.

Новая версия зацикливается навсегда и создает новый поток для каждого нового соединения. Теперь я не могу закрыть сокетное соединение.

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

код сервера

while(true)
            {
                ///////////////////////////////////////////////////
                // get a new connection
                ///////////////////////////////////////////////////
                System.out.println("Aceepting connections on port 1030 \r");

                try{
                    // Get New Connection

                    // wait for ever on accepting new connections
                    server.setSoTimeout(0);  
                    connection=server.accept();

                    cConnection thread = new cConnection("thread3", connection);
             } catch(IOException ec)
             {
                    System.out.println(ec.getMessage());    
             }
}

код, который запускает сервер

Теперь каждое сообщение приходит в новом потоке, поэтому я не могу сказать ему, чтобы остановить и закрыть сокет.

Ответы [ 3 ]

2 голосов
/ 30 ноября 2011

Вам необходимо предоставить флаг, который должен быть доступен глобально, поэтому, когда какой-либо клиент хочет остановить сервер, измените переменную и остановите цикл. Например:

class YourServer {
  private static boolean execute = true;

  public static  synchronized void stop() {
    execute = false;
  }
  public void yourMethod() {
     while(execute) {
         // implement your server here
     }
  }
}

Когда клиент отправляет команду STOP, вы должны сделать

  YourServer.stop();
0 голосов
/ 15 декабря 2011

Глядя на вашу проблему, я понял одну вещь, так как вы ставите

while (true), поэтому ваш элемент управления всегда застревает в connection = server.accept (); прослушивание нового соединения. Поэтому, чтобы остановить сокеты, вам нужно сначала найти способ прекратить зацикливание в цикле while. Либо вы можете установить переменную, например, (int clientsConnected), чтобы проверить количество клиентов, когда это заканчивается, останавливая цикл while. Так что вы можете остановить свои розетки.

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

    class GetNamesFromServer implements Runnable
    {  
      private Socket sForName, sForId;

      private BufferedReader in, inForName, inForId;
      private PrintWriter outForName, outForId;

      private static String clientNames;

      public GetNamesFromServer(Socket s1, Socket s2)
      {
        sForName = s1;
        sForId = s2;    
      }

      public void run()
      {    
        try
        {
          outForName = new PrintWriter(sForName.getOutputStream(), true);
          outForName.println(Client.clientName);
          System.out.println("Send Name : " + Client.clientName);
          outForName.flush();
        }
        catch(IOException e)
        {
          System.err.println("Error sending Name to the Server.");
        }

        try
        {
          inForId = new BufferedReader(new InputStreamReader(sForId.getInputStream()));
          Client.clientId = (inForId.readLine()).trim();
          System.out.println("Client ID is : " + Client.clientId);
        }
        catch(IOException e)
        {
          System.err.println("Error Receiving ID from Server.");
        }

        try
        {
          inForName = new BufferedReader(new InputStreamReader(sForName.getInputStream()));
          while (true)
          {        
            clientNames = inForName.readLine();
            if (clientNames != null && clientNames != "")
            {
               clientNames = clientNames.substring(1, clientNames.length() - 1);
               System.out.println("Names Received : " + clientNames);        
               String[] names = clientNames.split(", ");
               Client.nameClients.clear();
               for (String element: names)
                  Client.nameClients.add(element);
               Client.nPane.setText("");
              int size = Client.nameClients.size();
              System.out.println("Size of list : " + size);
              for (int i = 0; i < size; i++)
              {          
                 String name = Client.nameClients.get(i);          
                 String colour = Character.toString(name.charAt(0));
                 name = name.substring(1, name.length()) + "\n";
                 appendToNamePane(name, ReceiveMessages.getColour(Integer.parseInt(colour)),    "Lucida Console");
              }
              System.out.println("Clients Online : " + Client.nameClients);          
            }
          int index = Client.nameClients.indexOf(Client.clientId + Client.clientName);
          **if (index == -1)
          {
             sForName.close();
             break;
          }**
        }
      }
      catch(IOException e)
      {
        System.err.println("Error Receiving Names of Clients from Server");
      }
    }

НОВОЕ ИЗДАНИЕ: Вы можете добавить ограничение к максимальному количеству клиентов, которые могут подключиться, как только он достигнет вашего цикла while, не перейдет к connection = server.accept(); и, следовательно, когда они закончат общаться (через некоторое время), то есть totalClients = 0, вы можете остановить ваши сокеты, чтобы остановить программу.

if (totalClients == 0)
{
  socket.close();
  serverSocket.close();
}

Привет

0 голосов
/ 30 ноября 2011

Если вы хотите, чтобы команда останова остановила сервер, вы можете вызвать System.exit (), чтобы заставить программу сохранить или просто закрыть server, вероятно, все, что вам нужно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...