【问题标题】:BufferedReader readLine method hangs and block programBufferedReader readLine 方法挂起并阻塞程序
【发布时间】:2011-12-12 22:31:40
【问题描述】:

我正在尝试使用 Java 学习套接字,并且成功地将数据发送到在我自己的机器上运行的 ServerSocket。当我尝试使用 readline 从此套接字读取数据时(这样我就可以回显自己发送的消息),我的程序挂起并且不会返回。

代码如下:

public static void main(String[] args) throws UnknownHostException, IOException {

    TCPClient cli = new TCPClient("127.0.0.1", "15000");
    try {
        cli.ostream.writeUTF("Teste");
        String echo = cli.istream.readLine(); //it hangs in this line
        System.out.println(echo);
    }

TCPClient 是我定义的一个类,因此我可以在我的 homwework 上使用 swing 之前在更简单的接口上测试我的程序。这是代码:

public class TCPClient {

public DataOutputStream ostream = null;
public BufferedReader istream = null;

public TCPClient(String host, String port) throws UnknownHostException {
    InetAddress ip = InetAddress.getByName(host);

    try {
        Socket socket = new Socket(host, Integer.parseInt(port));

        ostream = new DataOutputStream(socket.getOutputStream());
        istream = new BufferedReader(new InputStreamReader(socket.getInputStream()));


    } catch (IOException ex) {
        Logger.getLogger(TCPClient.class.getName()).log(Level.SEVERE, null, ex);
    }

}

我的服务器很简单。建立连接后,它进入此循环并一直停留在这里,直到我关闭客户端(因为无限循环)。之后,一些异常处理会将其返回到连接开始之前的位置。

            while(true){
                String msg = istream.readLine();
                System.out.println("Arrived on server: " + msg); //just works on debug
                ostream.writeUTF("ACK: " + msg);
                ostream.flush();
            }

我看不出我错过了什么。

PS:奇怪的是,如果我调试服务器,我可以看到消息到达那里(例如,我可以打印它),但如果我只运行这段代码,这是不可能的。这是否有一些我忽略的并发关系?

谢谢

【问题讨论】:

  • 服务器是做什么的?如果它没有对你的消息做出任何回应,或者没有刷新它的写入,那么客户端当然会无限期地等待,直到从服务器发送一行
  • 我将在回显消息时使用服务器的无限循环编辑帖子

标签: java sockets


【解决方案1】:
cli.ostream.writeUTF("Teste");

这不应该包含一个新行吗?否则我认为 read 方法将等待换行。

还建议您在写入 ostream 后尝试刷新它。

【讨论】:

  • ostream 是输出流。 OP 表示服务器正确接收到此消息。问题是客户端没有收到服务器的答复。
  • 我现在刷新了 ostream 并在我的字符串中添加了一个 '\n',我以前没有这样做过。但是问题还是一样=/
【解决方案2】:

writeUTF() 不写一行。请参阅 Javadoc。 writeUTF() 与 readUTF() 一起使用。 Readers 与 Writers 一起使用。因此,将 DataOutputStream 更改为 BufferedWriter 并调用 write(),然后调用 newline()。

【讨论】:

  • 我相信我理解你所说的,但考虑到我不是以英语为母语的人,所以我需要 Unicode 支持。在我的案例中推荐的课程组合是什么?
  • @ThiagoMoraes 我有一个错字。使用 Readers 和 Writers 并指定字符集。
【解决方案3】:

问题是readLine 尝试读取一行。在确定已到达行尾之前,它不会返回该行。这意味着它需要换行符或通信结束。由于服务器不发送任何换行符并且不关闭流,客户端无限期地等待。

【讨论】:

  • 就是这样!在 ostream.writeUTF("ACK: " + msg); 中放置一个 '\n'工作。现在唯一的疑问是我的客户端上出现了 2 个不可打印的字符。它们会是什么?
  • 您在一侧使用 UTF 写入,在另一侧使用平台的默认编码读取。始终使用 Writer 来写字符。始终使用指定特定的显式编码的 OutputStreamWriter 包装输出流。对读取执行相同操作:始终使用 Reader,并使用指定相同特定编码的 InputStreamReader 包装输入流。
  • @Thiago Moraes 它们是由 writeUTF() 放在那里的长度词前缀,如 Javadoc 中所述。另请参阅我的回答。
  • 现在它可以正常工作了。我使用了 OutputStreamWriter 和 BufferedReader。但我仍然必须从客户端和服务器发送“\n”,以便一切正常。好的一面是,我不再遇到编码问题了。
  • @ThiagoMoraes 看到我的回答。都在里面。很好奇你把这个标记为正确。
猜你喜欢
  • 2018-09-26
  • 2013-08-10
  • 2020-12-05
  • 2011-08-24
  • 1970-01-01
  • 2017-07-09
  • 1970-01-01
  • 2018-02-24
  • 1970-01-01
相关资源
最近更新 更多