0

这是我的 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();
  }
}
4

1 回答 1

3

这意味着它要么返回 -1 要么 throws IOException。您实现了 2 个循环:内部循环验证 read 返回的值,如果值为 -1,则退出。这可以。然而,外循环while(true)使您一次又一次地进入读取,因此不再阻塞,因为达到了流的结尾。

编辑:归功于@assylias,他写了暗示这一点的评论。

于 2013-06-05T13:48:01.727 回答