【问题标题】:Tcp Socket: readine hangs if used in while loop at Client : javaTcp Socket:如果在客户端的while循环中使用readine挂起:java
【发布时间】:2011-10-24 23:41:11
【问题描述】:

我一直在敲我的头试图找出问题所在。

我正在 java 中尝试一个简单的服务器客户端 TCP 套接字。服务器可以发送多行作为响应。
我在客户端使用while((str = in.readLine())!= null),它在阅读响应后挂起。请在下面找到代码。我发帖前已经搜索过了。我确保我以新行结束响应。

我尝试了 \n、\r\n 的组合,但 readLine 没有检测到行尾。
但它在服务器端运行良好。

请帮忙。

谢谢。

服务器:

import java.net.*;
import java.io.*;
public class SimpleServer {
public static void main(String args[]) throws IOException {

    ServerSocket s = new ServerSocket(55555);
    Socket socket = s.accept();

    BufferedReader in = new BufferedReader(
            new InputStreamReader(socket.getInputStream()));

    PrintWriter out = new PrintWriter(socket.getOutputStream(), true);

    String inputLine= null;
    System.out.println("call processInput"); 

       while ((inputLine = in.readLine()) != null) {
           System.out.println("before call processInput");           
           out.print("200 Success \r\n");
           out.flush();
           System.out.println("after call processInput: ");            
    }
    System.out.println("after while");
    out.close();
    in.close();
    socket.close();
    }
}

客户:

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.nio.CharBuffer;

public class Test {
     public static void main(String[] args) throws IOException {

          try {

              System.out.println(":Connect");
                  Socket s = new Socket("192.168.1.114",55555);
                  System.out.println("Socket:" + s); 


                  System.out.println("after :Connect");



                  OutputStream s1out = s.getOutputStream();


                  PrintWriter output = new PrintWriter(s1out, true);   
                  output.println("login user root");
                  output.flush();


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

                  System.out.println( in.readLine());



                  output.println("servershare");
                  output.flush();
                  System.out.println( "servershare");
                  String str = null;


             while((str = in.readLine())!= null) // hangs here
             {
                  System.out.println(str);

              }


               System.out.println( "share");
               output.println("share file1.txt file1.html, roopa ramesh");
                   str = null;
                   while((str = in.readLine())!= null && !str.equals(""))
                  System.out.println(str);

                  in.close();
                  output.close();
                  s.close();







          } catch (UnknownHostException e) {

                  // TODO Auto-generated catch block

                  e.printStackTrace();

          } catch (IOException e) {

                  // TODO Auto-generated catch block

                  e.printStackTrace();

          } 
     }
}

【问题讨论】:

    标签: java sockets tcp client-server readline


    【解决方案1】:

    你有一个死锁:

    1. 客户端发送登录信息
    2. 服务器读取登录行并发送 200 OK,并等待下一行
    3. 客户端读取 200 OK
    4. 客户端发送服务器共享
    5. 服务器读取 servershare 行,发送 200 OK,等待下一行
    6. 客户端读取 200 OK,等待下一行

    客户端和服务器都在等待另一端的下一行。您的协议不正确。

    此外,您在服务器端和客户端使用平台默认编码来读取和写入消息。如果客户端和服务器没有相同的默认编码,你就会遇到问题。您应该使用输入/输出流编写器包装您的流,并在构造它们时指定特定的编码。

    【讨论】:

    • Hi 协议是请求或响应应以 \r\n 结尾,如果它是多行,则每行应以 \r 结尾。 readline 还应该在客户端检测到行尾并退出。因此,如果服务器发送多行作为响应,如何在不使用 while 循环的情况下在客户端读取它??。谢谢
    • BufferedReader 的 readLine 方法将 \r、\n 和 \r\n 视为有效的行尾。如果您需要为 \r 和 \r\n 做一些不同的事情,您应该自己逐个字符地阅读。此外,当读取一行时,您的循环不会停止。它在 readLine 返回 null 时停止,即当流中没有更多内容可读取时。停止此循环的唯一方法是让服务器关闭输出流。
    • 嗨,谢谢。但是我如何检查读取的字符是否为 \r\n ,因为它是两个字符。我是否要记住我以前读过的内容,如果后面跟着\n,请确认它的\r\n。
    • 对不起,请详细说明一下。我不太明白。
    • BufferedReader 有一个标记和一个重置方法。它们可能对实现您的协议很有用。阅读他们的 javadoc。
    猜你喜欢
    • 2017-06-11
    • 1970-01-01
    • 2017-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-26
    • 2013-10-19
    • 2012-08-24
    相关资源
    最近更新 更多