第二次调用后,Socket read()不会阻塞

时间:2013-06-05 13:42:22

标签: java sockets

这是我的Socket测试程序。 我的问题是当我执行下面的代码时。在我第一次调用Socket InputStream上的read()之后,它会按预期阻塞。 但是当循环再次返回read()时,它永远不会再次阻塞read()?因此,它最终会形成一个紧密无限的循环。

如果我想使用单独的线程来获取服务器响应,我该怎么办?这个要求有没有设计模式?

package test.socket;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;

public class TestMario {

  private InputStream in;
  private OutputStream out;

  public static void main(String[] args) throws Exception {

    new TestMario().go();
  }

  public TestMario() {

    try {
      Socket echoSocket = new Socket("xxx.xxx.xxx.xxx", 1234);
      in = echoSocket.getInputStream();
      out = echoSocket.getOutputStream();

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

  public void go() throws UnknownHostException, IOException {

    Thread writer = new Thread(new Runnable() {

      public void run() {
        BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
        PrintWriter writer = new PrintWriter(out);
        String userInput;
        try {
          System.out.print("input your command:");
          while ((userInput = stdIn.readLine()) != null) {
            System.out.println("you type:" + userInput);
            writer.print(userInput);
            writer.flush();
          }
        } catch (IOException e) {
          e.printStackTrace();
        }
      }

    });

    Thread reader = new Thread(new Runnable() {

      StringBuffer sb = new StringBuffer();

      public void run() {

        while (true) {
          System.out.println("waiting for server response...");
          try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();  
            byte[] content = new byte[512];  
            int bytesRead = -1;  
            while((bytesRead = in.read(content)) != -1) { // read() doesn't block anymore after first read
              baos.write(content, 0, bytesRead);  
            } // while
            System.out.println("got:" + new String(baos.toByteArray())); 
          }
          catch (Exception e) {
            e.printStackTrace();
          }
        }
      }

    });

    writer.start();
    reader.start();

    System.out.println();
  }
}

1 个答案:

答案 0 :(得分:3)

这意味着它返回-1或抛出IOException。您实现了2个循环:内部循环验证read返回的值,如果value为-1则退出。这可以。但是,外循环while(true)会让您一次又一次地输入读取,因此它不再被阻止,因为实现了流的结束。

编辑:写给@assylias的信用评论提示这一点。