无法让服务器套接字关闭

时间:2011-11-29 20:38:40

标签: java sockets tcp

我正在创建一个简单的聊天服务器,并且只是在每个连接都在新线程上运行。

旧版本为服务器启动了一个单独的线程,它执行了一个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 个答案:

答案 0 :(得分:2)

您需要提供一个必须全局可访问的标志,因此当某个客户端想要停止服务器然后更改变量时会停止该bucle。例如:

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();

答案 1 :(得分:0)

如果你想要一个停止命令来停止服务器,你可以调用System.exit()强制程序存储或只关闭server可能就是你所需要的。

答案 2 :(得分:0)

考虑到你的问题,我明白了一件事,因为你要放

while(true),所以你的控件总是卡在connection = server.accept();正在寻找新的连接。因此,为了停止套接字,您需要首先找到一种方法来停止循环中的循环。你可以设置一个变量,比如(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();
}

此致

相关问题