2013-04-22 71 views
0

很难将其纳入标题中,但每次客户端断开连接时,都会引发很多异常,并且服务器在DC之后不允许有更多连接。这里是我得到的错误:多客户端聊天服务器抛出异常,并且在断开连接后不允许连接

java.net.SocketException: Socket closed 
at java.net.SocketInputStream.read(Unknown Source) 
at java.net.SocketInputStream.read(Unknown Source) 
at java.io.ObjectInputStream$PeekInputStream.read(Unknown Source) 
at java.io.ObjectInputStream$PeekInputStream.readFully(Unknown Source) 
at java.io.ObjectInputStream$BlockDataInputStream.readShort(Unknown Source) 
at java.io.ObjectInputStream.readStreamHeader(Unknown Source) 
at java.io.ObjectInputStream.<init>(Unknown Source) 
at ClientHandler.setupStreams(ClientHandler.java:34) 
at ClientHandler.run(ClientHandler.java:22) 

现在我期望得到这个异常,因为是...客户端关闭了服务器和客户端之间的连接。但我不明白的是为什么客户端在第一次断开连接之后不会允许连接。我假设它打破了while循环,但为什么?下面是采取客户端的连接,接受它,并把它关闭的处理程序类代码:

public class ClientConnector 
{ 
public static JTextField userText; 
public static JTextArea chatWindow; 
public static int Connections = 0; 
public static Vector sendQueue = new Vector(); 
public static ArrayList<ObjectOutputStream> Streams = new ArrayList<ObjectOutputStream>(); 
public static Scanner input = new Scanner(System.in); 


public ClientConnector() 
{ 

} 

public static void runServer() 
{ 
    try 
    { 
     System.out.println("[Info] Attempting to bind to port 1337."); 
     @SuppressWarnings("resource") 
     ServerSocket serversocket = new ServerSocket(1337); 
     System.out.println("[Info] Bound to port 1337."); 
     System.out.println("[Info] Waiting for client connections..."); 
     while(true) 
     { 
      Socket socket = serversocket.accept(); 
      new ClientHandler(socket).start(); 
      Connections += 1; 


     } 
    } 
    catch (IOException e) 
    { 
     e.printStackTrace(); 
    } 
} 
} 

这是相当简单的。现在处理客户端连接的代码:

public class ClientHandler extends Thread 
{ 
Socket ConnectedClient; 
static ObjectOutputStream Output; 
static ObjectInputStream Input; 
public static boolean isError = false; 
public static int updateCounter = 0; 

ClientHandler(Socket socket) 
{ 
    ConnectedClient = socket; 
} 

public void run() 
{ 

    while(true) 
    { 
     setupStreams();//22 
     WhileChatting(); 
    } 
} 

public void setupStreams() 
{ 
    try 
    { 
     if(isError == false) 
     { 
      Output = new ObjectOutputStream(ConnectedClient.getOutputStream()); 
      Input = new ObjectInputStream(ConnectedClient.getInputStream());//34 
      ClientConnector.Streams.add(Output); 
     } 
    } 
    catch (IOException e) 
    { 
     isError = true; 
     e.printStackTrace(); 
    } 

} 


public static void WhileChatting() 
{ 
    String Message = ""; 
    do 
    { 
     try 
     { 
      if(isError == false) 
      { 
       Message = (String)Input.readObject(); 
       for(int i = 0; i < ClientConnector.Streams.size(); i++) 
       { 
        ClientConnector.Streams.get(i).writeObject(Message); 
        System.out.println(Message); 
       } 
      } 

     } 
     catch(ClassNotFoundException CNFE) 
     { 
      isError = true; 
      CNFE.printStackTrace(); 
     } 
     catch(EOFException eof) 
     { 
      for(int i = 0; i < ClientConnector.Streams.size(); i++) 
      { 
       try 
       { 
        Output.close(); 
        Input.close(); 
        ClientConnector.Streams.get(i).close(); 
        ClientConnector.Streams.remove(i); 
        System.out.println("Connection lost"); 
       } 
       catch (IOException e) 
       { 
        e.printStackTrace(); 
       } 

      } 
     } 
     catch (IOException e) 
     { 
      isError = true; 
      e.printStackTrace(); 
     } 

    } 
    while(Message != "/disconnect"); 
} 

public static void sendMessage(String message) 
{ 
    try 
    { 
     if(isError == false) 
     { 
      Output.writeObject(message); 
      System.out.println(message); 
     } 
    } 
    catch(IOException Ex) 
    { 
     isError = true; 
     Ex.printStackTrace(); 
    } 
} 

public static void sendServerMessage(String message) 
{ 
    int Limit = 0; 
    try 
    { 
     for(int i = 0; i < ClientConnector.Streams.size(); i++) 
     { 
      if(Limit == 0) 
      { 
       ClientConnector.Streams.get(i).writeObject("\247c[Server] \247d" + message); 
       System.out.println("\247c[Server] \247d" + message); 
       Limit = 1; 
      } 
     } 
    } 
    catch (IOException e) 
    { 
     e.printStackTrace(); 
    } 
} 

public static void closeConnections() 
{ 
    try 
    { 
     if(isError == false) 
     { 
      Output.close(); 
      Input.close(); 
      //ConnectedClient.close(); 
     } 
    } 
    catch(IOException Ex) 
    { 
     isError = true; 
     Ex.printStackTrace(); 
    } 
} 

} 

我已在受影响的行中发表了评论。 客户端断开连接后发生错误。我不知道是否是导致while循环中断或天气变化的异常。我怎样才能让这段代码在客户端断开连接后继续传入connectinos。我试过调试并使用System.out.println。在此先感谢所有回答的人。

回答

0

现在我期望得到这个异常,因为是...客户端关闭了服务器和客户端之间的连接。

号此异常意味着关闭Socket,然后试图做进一步的I/O就可以了。与同伴无关。

但我不明白的是为什么客户端不会允许第一次断开连接后连接。

你的代码有很多问题。

  1. 您必须使用相同的ObjectInputStreamObjectOutputStreamSocket的生活,在两端。目前,您正在创建一个新对,并且每次在循环中将它们添加到数据结构中。

  2. 当你赶上EOFException一个Socket,你正在关闭所有插座。您应该只关闭一个,您从中获得例外,然后,然后您必须跳出所有循环并允许线程退出。

  3. 你应该基本上是从while (true)改变你while回路while (!isError)和停止测试isError其他任何地方。我将摆脱whileChatting方法,并将其纳入此while循环。而且你不需要内部的do循环。您只需要一个读取EOS或断开连接命令的循环。