2010-06-09 370 views
1

伙计们有谁能告诉我我在这里做什么错了?下面是四个文件Client,main,Server,main。尝试从Server.readLine()尝试完成后,客户端发生错误。
错误:在客户端软件错误造成连接中止:recv的失败客户端/服务器应用程序

  package client; 
      import java.io.*; 
      import java.net.*; 
      import java.util.Scanner; 

      public class Client 
      { 
      private PrintWriter toServer; 
      private BufferedReader fromServer; 
      private Socket socket; 
      public Client()throws IOException 
       { 
       socket = new Socket("127.0.0.1",3000); 
      } 
      public void openStreams() throws IOException 
       { 

      // 
      //  InputStream is = socket.getInputStream(); 
      //  OutputStream os = socket.getOutputStream(); 
      //  fromServer = new BufferedReader(new InputStreamReader(is)); 
      //  toServer = new PrintWriter(os, true); 

       toServer = new PrintWriter(socket.getOutputStream(),true); 
       fromServer = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
      } 
      public void closeStreams() throws IOException 
       { 
       fromServer.close(); 
       toServer.close(); 
       socket.close(); 
      } 
      public void run()throws IOException 
       { 
       openStreams(); 
       String msg = ""; 
       Scanner scanner = new Scanner(System.in); 
       toServer.println("Hello from Client."); 
      // msg = scanner.nextLine(); 
       while (msg != "exit") 
       { 
        System.out.println(">"); 
      //  msg = scanner.nextLine(); 
        toServer.println("msg"); 
        String tmp = fromServer.readLine(); 
        System.out.println("Server said: " + tmp); 
       } 
       closeStreams(); 
      } 
      } 



     package server; 
     import java.net.*; 
     import java.io.*; 

     public class Server 
     { 
     private ServerSocket serverSocket; 
     private Socket socket; 
     private PrintWriter toClient; 
     private BufferedReader fromClient; 
     public void run() throws IOException 
      { 
      System.out.println("Server is waiting for connections..."); 
      while (true) 
      { 
       openStreams(); 
       processClient(); 
       closeStreams(); 
      } 

     } 
     public void openStreams() throws IOException 
      { 
      serverSocket = new ServerSocket(3000); 
      socket = serverSocket.accept(); 
      toClient = new PrintWriter(socket.getOutputStream(),true); 
      fromClient = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
     } 
     public void closeStreams() throws IOException 
      { 
      fromClient.close(); 
      toClient.close(); 
      socket.close(); 
      serverSocket.close(); 
     } 
     public void processClient()throws IOException 
      { 
      System.out.println("Connection established."); 
      String msg = fromClient.readLine(); 
      toClient.println("Client said " + msg); 
     } 
     } 


    package client; 

    import java.io.IOException; 


    public class Main { 

     /** 
     * @param args the command line arguments 
     */ 
     public static void main(String[] args) { 
      // TODO code application logic here 

      try 
      { 
       Client client = new Client(); 
       client.run(); 
      } 
      catch(IOException e) 
      { 
       System.err.println("Error in Client " + e.getMessage()); 
      } 
     } 

    } 



package server; 

import java.io.IOException; 


public class Main { 

    /** 
    * @param args the command line arguments 
    */ 
    public static void main(String[] args) { 
     // TODO code application logic here 
     Server server = new Server(); 
     try 
     { 
     server.run(); 
     } 
     catch(IOException e) 
     { 
      System.err.println("Error in Server " + e.getMessage()); 
     } 
    } 

} 
+3

您打算告诉我们错误是什么,或者我们猜测? – skaffman 2010-06-09 07:40:15

+0

@skaffman对不起,我忘了它。我已更新我的原始帖子 。 – 2010-06-09 07:48:46

+0

@EJP和Miklos谢谢你们的回答。 – 2010-06-09 13:46:30

回答

2

你的服务器端的所有混合起来。您需要另一个类,称为Connection或ConnectedClient,它实现了Runnable;将Socket作为构造函数参数;并为特定客户端执行所有服务器端I/O。目前你已经将这一切与你的服务器类混淆了。所有你的服务器类应该做的就是创建一个ServerSocket,并进入一个循环,接受Sockets并创建Connection对象并为它们启动线程。 Server的run()方法中的Socket对象只是一个本地对象,并且相关的输入/输出流或读写器属于Connection类,而不属于Server类。

这样,您可以同时处理多个客户端,而不需要彼此踩到彼此的脚趾。

您的下一个问题是,readLine()在另一端关闭连接时返回null。每次调用readLine()时,必须在进行任何其他处理之前测试此的第一个

接下来,如果在使用Socket时发生SocketException或IOException以外的SocketException或IOException,那么它将死亡 - 关闭它,忘记该客户端并退出线程(如果它发生在服务器中)。

2

发布的代码在客户端的无限循环中运行。 猜测取消注释(以Client.java最后scanner.nextLine())这行之后,我发现了以下问题:

  1. 客户端保持连接打开,但在接收到第一消息后,服务器关闭。
  2. 谓语msg != "exit"始终是真实的在Java中 - 使用String.equals()

的工作Server.processClient是:

public void processClient()throws IOException 
{ 
    String msg = null; 
    do { 
     msg = fromClient.readLine(); 
     toClient.println("Client said " + msg); 
    } while (!"exit".equals(msg)); 
} 

的工作Client.run是:

public void run()throws IOException 
{ 
    openStreams(); 
    String msg = ""; 
    Scanner scanner = new Scanner(System.in); 
    while (!"exit".equals(msg)) 
    { 
     System.out.print(">"); 
     msg = scanner.nextLine(); 
     toServer.println(msg); 
     String tmp = fromServer.readLine(); 
     System.out.println("Server said: " + tmp); 
    } 
    closeStreams(); 
} 

+评论:我专注于纠正明显的错误。 EJP的答案为您提供了很好的指导方法,使您的代码更好,包括处理同时连接,正确使用线程等。