2011-06-15 84 views
5

我在写一个客户端应用程序,它将通过tcp/ip接收连续的数据流。我遇到的问题是缓冲读取器对象没有收到任何数据,并且挂在readline方法中。缓冲阅读器没有从套接字接收数据

服务器的工作方式是连接到它,然后发送验证信息以接收数据。我的代码的要点是下面

socket = new Socket(strHost, port); 
authenticate(); 
inStream = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
process(inStream); 

authenticate() 
{  
    PrintWriter pwriter = new PrintWriter(socket.getOutputStream(), true); 
    pwriter.println(authString); 
} 

process(BufferedReader bufferedReader) 
{ 
    while((line = bufferedReader.readLine()) != null) 
     dostuff 
} 

我创建的发送数据的方式(我认为)服务器发送数据,并将其连接,并接收和处理所述数据细的样本服务器应用程序。我可以在我的应用程序中连接到服务器。我也可以telnet到服务器并写入验证字符串,并使用telnet接收大量数据。然而,我的应用程序只是挂在readLine与服务器,我不知道为什么。

的数据进来(通过telnet ATLEAST)看起来像下面的连续流:

data;data;data;data;data 
data;data;data;data;data 

应用程序为什么会在挂readline的,我不能正确输出验证线?我没有收到任何错误...

编辑 我的示例服务器代码(正常工作)...这同样是模仿仅一路我觉得真正的服务器在运行,但我可以连接到我的应用程序只是没有从真正的服务器接收数据。

public static void main(String[] args) throws IOException 
    { 
    ServerSocket serverSocket = null; 

    try 
    { 
    serverSocket = new ServerSocket(1987); 
    } 
    catch (IOException e) 
    { 
    System.out.println("Couldn't listen on port: 1987"); 
    System.exit(-1); 
    } 

    Socket clientSocket = null; 
    try 
    { 
    clientSocket = serverSocket.accept(); 
    } 
    catch (IOException e) { 
    System.out.println("Accept failed: 1987"); 
    System.exit(-1); 
    } 

    PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true); 
    BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); 
    String something; 

    while ((something = in.readLine()) != null) 
    { 
    while(true) 
    { 
     out.println(message); 
    } 
    } 



    out.close(); 
    in.close(); 
    clientSocket.close(); 
    serverSocket.close(); 
} 
+0

,你能否告诉我们有关问题的服务器代码? – Coeffect 2011-06-15 15:09:55

+0

'我可以在我的应用程序中连接到服务器。'你的意思是你的虚拟示例服务器? – leonbloy 2011-06-15 15:16:39

+0

也许您应该准备好另一个线程来读取您的数据_before_您发送身份验证?我假设服务器只要获取密码就开始泛滥数据。 – toto2 2011-06-15 15:23:10

回答

10

首先,你应该叫readLine(),为ready()会告诉你它是否可以读取之前调用BufferedReader.ready()

PrintWriter不会抛出I/O异常,所以如果没有您的知识,写入可能失败,这就是为什么没有东西可读。使用PrintWriter.checkError()来查看写入过程中是否有任何问题。

在向管道写入任何内容之前,您应该同时在Socket上设置输入和输出流。如果您的阅读器在另一端尝试写入时没有准备好,则您将在服务器中获取损坏的管道,并且不会再发送任何数据。 Telnet在写入或读取任何内容之前设置读取和写入。

您可以利用Wireshark来判断服务器是否实际发送数据。

+1

bufferedreader.ready似乎在做诀窍,感谢printwriter.checkerror的提示以及我将它添加到我的代码中。 – Ryan 2011-06-15 15:55:46

+0

@DavidNewcomb为什么我应该在发送内容之前从套接字的InputStream中设置一个BufferedReader?它真的会吃预先到达的数据吗?这对于始终具有初始数据的数据源如何工作? - 我期望任何Stream包装器获取,但不吃初始数据? – 2013-01-10 16:16:01

+1

对于BufferedXxx,你不能说读取或写入实际发生的时间。沟通渠道是管道,管道必须有读者和作家一起工作。它不会吃数据,如果你试图写一些东西并且没有东西可以读取它,那么你会得到一个破损的管道,就像没有人在另一端写入时读取会阻塞一样。 – 2013-01-10 20:01:39

8

BufferdReader.readLine()读取行,即以\r\r\n结尾的字符序列。我猜你的服务器把它的输出写入一行。你的telnet输出证明了这个假设。只需在服务器端使用PrintWriter.println()即可。

+1

或者他将不得不使用'read(char [] cbuf,int off,int len)'如果它是一个很长的连续流。 – toto2 2011-06-15 15:41:03

-1

我 与插座这项工作没有冲洗

void start_listen() 
    { 
     String result1=""; 
     char[] incoming = new char[1024]; 
     while (!s.isClosed()) 
     { 
      try { 

      int lenght = input.read(incoming); 
       result1 = String.copyValueOf(incoming,0,lenght); 


      } 
      catch (IOException e) 
      { 
       e.printStackTrace(); 
      } 
      Log.d("ddddddddddd",result1); 

     }