2014-02-17 324 views
1

我目前很难理解为什么我的代码不工作。我在下面列出了我的客户端和服务器代码。我发现我的问题发生在while循环的某个地方,但我不确定如何修复它,以免它卡住。我在论坛上搜索了一段时间,有人说添加一个换行符会解决它,但我仍然有麻烦。Java TCP客户端服务器挂起?

我的主要问题是如何避免过程卡住和通信不正常。外面的任何人都能指引我走向正确的方向吗?

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.io.PrintStream; 
import java.net.Socket; 
import java.net.UnknownHostException; 


public class My_Client { 

public static void main(String[] args) throws UnknownHostException, IOException { 

    Socket s = new Socket("localhost", 5555); 

    BufferedReader r = new BufferedReader(new InputStreamReader( 
      s.getInputStream())); 

    PrintStream w = new PrintStream(s.getOutputStream()); 

    w.print("hello world"); 
    w.print('\n'); 

    String line; 

    while ((line = r.readLine()) != null) { 
     System.out.println("Received: " + line); 

     //System.out.println("Error"); 
    } 
    w.close(); 
} 
} 

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.io.PrintStream; 
import java.net.ServerSocket; 
import java.net.Socket; 

----------------------------------------------------------------- 
public class My_Server { 

private static final int PORT = 5555; 

public static void main(String[] args) { 
    try { 
     ServerSocket ss = new ServerSocket(PORT); 
     System.out.println("Server Socket Created"); 

     while (true) { 

      System.out.println("Waiting on connection"); 
      Socket cs = ss.accept(); 
      System.out.println("Client connected"); 

      BufferedReader r = new BufferedReader(new InputStreamReader( 
        cs.getInputStream())); 
      PrintStream w = new PrintStream(cs.getOutputStream()); 

      String line; 

      while ((line = r.readLine()) != null) { 
       w.print(line + "!!!!"); 
       w.print('\n'); 
      } 

      System.out.println("Client disconnected"); 
      r.close(); 
     } 

    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

    } 

} 
+1

可能重复[服务器/客户端不通过套接字\ [Java \]发送或接收数据?](http://stackoverflow.com/questions/21199644/server-client-not-sending-or-receiving-data通过套接字-java)或其他任何数量的。如果您不使用println(),则需要'flush()' –

+1

尽管我没有使用PrintWriter。这是如何重复的?你知道这是否直接适用于我的问题? –

回答

2

两端读书,直到EOS也不是关闭,直到以后。所以你有一个典型的僵局。你需要重新考虑你的应用协议。

需要告诉你的PrintStreamPrintWriter到自动刷新,否则打电话flush()自己,但是这是一个相对较小的事情相比,上述的错误。

+0

因此,在查看答案后,有人(Sanjeev)建议我从客户端编写一个字符串“[END]”,并在服务器中检查以结束循环, 。这是处理这个问题的适当方法吗?我可以看到双方如何同时阅读可能导致问题,但我想知道这是解决这个问题的正确方法还是黑客? –

+1

它会工作,但没有必要。您可以关闭套接字进行输出,而不是发送特定的应用程序协议消息。这会导致同行的'readLine()'方法返回'null',而你离开。 – EJP

+0

谢谢,这很好! –

2

检查意见

,并确保你的服务器端的控制台中看到Client Connected

CLIENT SIDE 
    import java.io.BufferedReader; 
    import java.io.IOException; 
    import java.io.InputStreamReader; 
    import java.io.PrintStream; 
    import java.net.Socket; 
    import java.net.UnknownHostException; 


    public class My_Client { 

    public static void main(String[] args) throws UnknownHostException, IOException { 

     Socket s = new Socket("localhost", 5555); 

     BufferedReader r = new BufferedReader(new InputStreamReader( 
       s.getInputStream())); 

     PrintStream w = new PrintStream(s.getOutputStream()); 

     w.print("hello world"); 
     w.print("\n"); // enter new line 
     w.flush();// flush the outputstream 
     String line; 

     while ((line = r.readLine()) != null) { 
      System.out.println("Received: " + line); 

      //System.out.println("Error"); 
     } 
     w.close(); 
    } 
    } 
    SERVER SIDE 
    ---------------------------------------------------------- 
    import java.io.BufferedReader; 
    import java.io.IOException; 
    import java.io.InputStreamReader; 
    import java.io.PrintStream; 
    import java.net.ServerSocket; 
    import java.net.Socket; 

    public class My_Server { 

    private static final int PORT = 5555; 

    public static void main(String[] args) { 
     try { 
      ServerSocket ss = new ServerSocket(PORT); 
      System.out.println("Server Socket Created"); 

      while (true) { 

       System.out.println("Waiting on connection"); 
       Socket cs = ss.accept(); 
       System.out.println("Client connected"); 

       BufferedReader r = new BufferedReader(new InputStreamReader( 
         cs.getInputStream())); 
       PrintStream w = new PrintStream(cs.getOutputStream()); 

       String line; 

       while ((line = r.readLine()) != null) { 
        w.print(line + "!!!!"); 
        w.print("\n");// entering new line 
       } 

       System.out.println("Client disconnected"); 
       r.close(); 
       w.close();// close w 
      } 

     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

     } 

    } 
+0

我试着刷新输出流并添加w.close(),但我仍然陷入困境。程序永远不会到达w.close()并且永远不会退出循环。 –

+0

你卡在哪里?服务器端循环还是客户端循环? –

+0

我不确定。我怎样才能确定这一点?我尝试在循环中放置一个字符串,以查看是否存在无限循环,但没有无限循环,这就是为什么它会令人困惑。它就像程序一起停止 –

2

你应该在你的PrintWriters使用自动冲洗是这样的:

PrintStream w = new PrintStream(cs.getOutputStream(),true); 

您可以设置一个PROTOCOL来结束通讯,如下所示:

在您的客户端:

w.println("[END]");

在您的服务器:

while (!(line = r.readLine()).equals("[END]")) { 

希望这有助于: