2012-10-28 94 views
1

我的程序工作正常,许多用户可以连接并向服务器发送命令。 但是,当用户使用命令向服务器发送垃圾邮件时,服务器会阻止所有其他客户端,并且服务器不会从垃圾邮件发送者以外的客户端接收消息。 这是为什么?Java TCP多线程问题

TCPAccept联系


package game.server; 

import java.io.IOException; 
import java.net.Socket; 

public class TCPAcceptConnections implements Runnable 
{ 
    public static Socket clientSocket = null;; 
    int clientID = -1; 

    public void run() 
    { 
     while(Main.TCP) 
     { 
      try 
      { 
       clientSocket = TCPServer.serverSocket.accept(); 
       System.out.println("Client Connected."); 
       clientID++; 

       new TCPClientManager(clientSocket, clientID).run(); 
      } 
      catch (IOException e) 
      { 
       System.out.println("Couldn't create client socket."); 
       System.exit(-1); 
      } 
     } 
    } 
} 

TCPClientManager:


package game.server; 

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.io.PrintWriter; 
import java.net.Socket; 

public class TCPClientManager implements Runnable 
{ 
    Socket client; 

    int clientID; 

    static PrintWriter out; 
    static BufferedReader in; 
    String inputLine, outputLine; 

    boolean destroy = false; 

    public TCPClientManager(Socket cs, int id) 
    { 
     try 
     { 
      client = cs; 
      clientID = id; 
      out = new PrintWriter(client.getOutputStream(), true); 
      in = new BufferedReader(new InputStreamReader(client.getInputStream())); 
     } catch(IOException e) 
     { 
      e.printStackTrace(); 
     } 
    } 

    public void run() 
    { 
     System.out.println("Created TCPManager for client."); 
     String command; 

     while(!destroy) 
     { 
      try 
      { 
       if((command = in.readLine()) != null) //If received something 
       { 
        System.out.println("Commad received: " + command); 
         System.out.println(" " + Commands.proccessCommand(command)); 
        System.out.println("Command proccessed"); 
       } 
       else 
       { 
        client.close(); 
        destroy = true; 
       } 
      } catch (IOException e) 
      { 
       try 
       { 
        client.close(); 
       } catch (IOException e1) 
       { 
        e1.printStackTrace(); 
        destroy = true; 
       } 
       System.out.println("Client lost connection."); 
       destroy = true; 
      } 
     } 
     System.out.println("TCPManager for client destroyed."); 
    } 
} 

命令:


package game.server; 

public class Commands 
{ 
    public static String proccessCommand(String command) 
    { 
     if(command.equalsIgnoreCase("cp")) 
     { 
      System.out.println("Creating player..."); 
       System.out.println(" Retrieved client"); 
      return "Player Created"; 
     } 
     else 
     { 
      return "Unkown command: " + command; 
     } 
    } 
} 
+1

仅供参考,除非您改变线程工作方式,否则不应该扩展'Thread'。在像你这样的情况下,你只需要一个'run'方法就可以让线程运行,实现'Runnable'并且说'new Thread(new TCPClientManager(clientSocket,clientID))。start();'获得相同的功能暗示线程的工作方式不同。 – cHao

回答

1

如果您收到未知命令,应记录它并关闭连接。

但是你有一个更严重的问题。当它读取空值时,您不停止客户端处理程序。所以一旦客户断开连接,阅读将永远无限地旋转。如果readLine()返回null,则必须关闭套接字并退出循环。如果您得到任何IOException,则还必须关闭套接字。

+0

这是为了成为一款游戏服务器,但我不希望它们在输入无效命令时断开连接。我如何经常检查是否有收到的命令,如果我只是停止它,如果它等于空? – BleedObsidian

+1

@BleedObsidian:如果'readLine'返回null,这意味着客户端已经关闭了连接的结束。你不会在这个连接上得到更多的命令。但是因为你没有退出循环,所以你只会一遍又一遍地阅读空。 – cHao

+0

好的,我已经更新了我的代码。但是现在如果有一个客户端已经连接,它将不会接收另一个客户端? – BleedObsidian