【问题标题】:BufferedWriter not flushing to a socket's outstream on OS XBufferedWriter 不刷新到 OS X 上的套接字的外流
【发布时间】:2015-09-18 11:18:09
【问题描述】:

我遇到了一个非常奇怪的问题,过去两天让我很沮丧。我试过在这里寻找类似的问题,但没有找到解决方案。

我正在使用套接字从远程 telnet 会话记录器读取 Java 文件。
我为输入和输出流定义了一个 BufferedWriter 和 Reader,并将每个 readLine 刷新到一个文件中。登录时,我得到一个特定的字符串,使用 outputStream 插入密码,然后开始循环读取 instream。这在 Windows 上运行良好,没有任何问题。

现在,我尝试在 Mac OS X (Yosemite) 上运行相同的代码。我得到第一行(要求我插入密码),通过调试我注意到我也在将密码写入 BufferedWriter。但是,出于某种奇怪的原因,在下一次 readLine 迭代中,代码没有得到日志输出,而是挂起,停留在下一个 readLine 实例上。如果它为空,则应该退出循环。我已经检查了在mac上手动打开一个telnet会话(使用secureCRT),它使用密码可以正常工作。在插入错误密码时,我还应该得到一行(“密码不正确)。但在下一个 readLine 上我什么也没得到,它只是卡住了。

这是我的代码,有人知道我在这里做错了什么吗?它应该在MAC上以不同的方式工作吗?它真的会救我在这里。谢谢!

这个片段是线程的一部分,但它与问题无关(或者我认为)。实际文件本身是在线程之外创建的。

public void run(){
    String line = "-1";

    try {
        socket = new Socket(JSONReader.getPropertyByName("files/properties.json", "LOGGER_DNS_NAME"), 5550);
    } catch (IOException e1) {        
      e1.printStackTrace();
    }

    try {            
        bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
        instream = new BufferedReader(new InputStreamReader(socket.getInputStream()));

        while ((line = instream.readLine()) != null) {         

            // Insert Username and Password in the Telnet session      
            line = instream.readLine();

            if(line.startsWith("Please")){                
                bw.write("password");
                bw.newLine();
                bw.flush();               
            }           

            if (line.startsWith("Press")) {
                System.out.println("Reached log");
                bw.write("d");
                bw.newLine();
                bw.flush();
            }

            if (Thread.interrupted()){
                try {
                    instream.close();
                    bw.close();
                    socket.close();
                    return;
                } catch (IOException e) {
                    e.printStackTrace();
                    System.out.println("Could not close socket");
                    System.exit(-1);
                }        
            }           
        }

        // Write the output to the log file           
        logfile.println(line);
        logfile.flush();
     } catch (UnknownHostException e) {
         System.out.println("Could not open Telnet session to the server");
         System.exit(1);
     } catch  (IOException e) {
         System.out.println("There was a problem with file creation, or I/O exception");
         System.exit(1);
     }
 }

【问题讨论】:

  • 你不使用 Java 7+ 吗?
  • 与您的问题无关,但您应该使用if(isInterrupted()) 而不是if(Thread.interrupted())。如需参考,请参阅here.
  • @fge 我使用的是 jre 1.8 - 有什么不同吗?
  • @MalaKa - 谢谢你,我会相应地改变它。
  • 是的;一方面,您应该使用 try-with-resources 语句

标签: java macos sockets bufferedreader bufferedwriter


【解决方案1】:

所以最后,在两种情况下都嗅探了服务器的 tcp 会话之后,我发现了我的问题。

问题在于 BufferedWriter 在使用 write 方法时,new line 和 flush 会自动生成行尾(\n)。除了在基于 linux 的 Mac OS 上,行尾应该是 (\r\n)。

所以,我没有使用“write”方法和“new line”,而是使用“append”插入了\r\n字符串(append ("password\r\n))。

【讨论】:

    猜你喜欢
    • 2016-01-22
    • 2011-10-16
    • 2014-08-10
    • 1970-01-01
    • 1970-01-01
    • 2014-07-05
    • 1970-01-01
    • 1970-01-01
    • 2018-10-07
    相关资源
    最近更新 更多