BufferReader意外行为

时间:2012-08-20 09:47:30

标签: java sockets bufferedreader serversocket printwriter

我正在尝试使用线程运行方法从套接字读取数据:

@Override
public void run() {
    while(true){
        try{
            String o = "";
            socketServer = new ServerSocket(port);
            System.out.println("Waiting for connection on port "+port+".");
            Socket socket = new Socket();
            socket = socketServer.accept();
            System.out.println("Connection got.");
            BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            int c;
            while(( c = input.read()) != -1)
                o += (char)c;
            PrintWriter output = new PrintWriter(socket.getOutputStream());
            output.println("ok");
            output.flush();
            output.close();
            input.close();
            socket.close();
            socketServer.close();
            textFieldMessage.setText("Сообщение от "+socket.getInetAddress().getCanonicalHostName()+":\n"+o);
        }catch(Exception e){
            e.printStackTrace();
            System.exit(-1);
        }

    }
}

但是它一直停留在循环中。调试器告诉最后没有-1值。 这有什么不对?

3 个答案:

答案 0 :(得分:1)

因为你是从Socket读取的,所以除非套接字或流已经关闭,否则你永远不会到达流的末尾。因此while循环将阻塞input.read(),因为在客户端关闭流/套接字之前它不会返回-1。

不确定您从套接字读取的是什么,但您可以尝试使用BufferedReader的readLine()方法。您可以提前知道需要多少行,也可以使用空白行(如HTTP)结束阅读。

答案 1 :(得分:1)

  

InputStream的read()方法阻塞,直到数据可用。

只有在检测到流的末尾时它才能返回-1。(虽然不应该是套接字的情况)所以如果数据不可用,循环将阻塞,即你的读取调用将等待数据被阅读。

注意:

但如果值为-1,那么您的程序应该退出。那你在读什么?

答案 2 :(得分:1)

对等体没有关闭套接字,所以你永远不会得到-1,所以你在收到最后一个字符后的read()调用中阻塞了。你的策略是有缺陷的。您正在阅读EOS,然后希望能够写回复。除非对等体关闭其套接字输出然后读取,否则这将无法工作。您需要正确定义应用程序协议。目前你期望同伴做写/关/读。没有意义。