第二个套接字写入似乎不会发送到网络

时间:2017-10-02 22:55:31

标签: java sockets client-server

我正在创建一个简单的网络客户端。它读取文本文件并将每行放入网络。 在远端,有一个服务器,它读取传入的线路并以CSV文本行进行响应。

我用于测试的传出文件很简单:

6216448319,Richard Nixon,登录
6216448319,Richard Nixon,退出

响应应该是,#34;已登录。"然后退出"退出。"

第一行处理完美,但第二行似乎写入套接字,服务器永远不会看到传入的消息。我已尽力遵循文档和各种教程,但我所见过的任何内容似乎都表现出相同的行为。我错过了什么?

如果我在自己的文件中发送每一行,服务器会正​​确响应。

protected Integer call() {
    LOG.info("Starting spooler for file {}, address {}:{}", spoolFile, ipAddress, port);
    InetAddress server = null;
    try {
        server = InetAddress.getByName(ipAddress);
        LOG.info("IP Address: {}", server.getHostAddress());
    } catch (Exception e) {
        LOG.error("Unknown host: {}", ipAddress, e);
    }
    try (Socket socket = new Socket(server, port);
         BufferedWriter socketWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
         //PrintWriter socketWriter = new PrintWriter(socket.getOutputStream(), true);
         BufferedReader socketReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
         BufferedReader fileReader = new BufferedReader(new InputStreamReader(new FileInputStream(spoolFile)))
    ) {
        // Read the spool file line by line and put it out on the wire.
        String line;
        while ((line = fileReader.readLine()) != null) {
            if (isCancelled()) {
                LOG.error("Spool has been cancelled.");
                break;
            }
            line = line.trim();
            LOG.info("OUT({}): [{}]", line.length(), line);
            //Wait until the channel has successfully written out the line.
            LOG.info("Socket is {} for write.", socket.isConnected() ? "connected" : "not connected");
            socketWriter.write(line);
            socketWriter.flush();
            TalkmanMessage outMessage = new TalkmanMessage(line);
            outMessageList.add(outMessage);
            // Wait for the network to respond.
            // Apparently, readline() blocks until a message is received.
            LOG.info("Waiting for response...");
            LOG.info("Socket is {} for read.", socket.isConnected() ? "connected" : "not connected");
            String msg = socketReader.readLine();
            LOG.info("IN({}): [{}]", msg == null ? null : msg.length(), msg);
            TalkmanMessage inMessage = new TalkmanMessage(msg);
            inMessage.setDelay(
                    Duration.between(outMessage.getTime(), inMessage.getTime()).toNanos());
            inMessageList.add(inMessage);
            //The readline() seems to leave a non-printing byte in the socket. Read that out.
            int leftOver;
            do {
                LOG.info("Socket is {} for EOL", socket.isConnected() ? "connected." : "not connected");
                leftOver = socketReader.read();
                LOG.info("Read {} from socket.", leftOver);
            } while (leftOver > -1);
        }
    } catch (Exception e) {
        LOG.error("Unable to read from file/write to .", e);
    }
    return 1;
}

日志记录命令产生以下输出:

OUT(29): [6216448319,Richard Nixon,Log In] 
Socket is connected for write.
Waiting for response... 
Socket is connected for read. 
IN(12): ["Logged in."]
Socket is connected for EOL 
Read 13 from socket. S
Socket is connected for EOL 
Read 10 from socket. 
Socket is connected for EOL 
Read -1 from socket. 
OUT(30): [6216448319,Richard Nixon,Log Out] 
Socket is connected for write. 
Waiting for response... 
Socket is connected for read. IN(null): [null] 
Socket is connected for EOL 
Read -1 from socket.

1 个答案:

答案 0 :(得分:1)

  1. 你忽略了流的结束。一旦read()返回-1,连接就会关闭。

  2. 持续测试socket.isConnected()是错误的。它并没有神奇地变得虚假​​。它不是对等断开连接的测试。

  3. 当然你应该把写给同伴吗?即在发送每一行后调用newLine()

  4. 事实上你应该只是复制字节,而不是读取行,删除/恢复行终止符,修剪等。使用流,而不是读者和作者。

    < / LI>
  5. 如果您正在假脱机,为什么期望每条线路都有响应?假脱机的本质是你只是写。并且返回的数据(下面)没有明显表明它是每行的响应。

  6. 您似乎正在尝试阅读已被newLine()删除的EOL。见Javadoc。这没有意义。而且你也试图通过阅读直到流的末尾,在你发送的每一行上来做到这一点,这就更没意义了。

  7. 服务器发送给您的内容如下:

    IN(12): ["Logged in."]<some line terminator, probably but not certainly CR LF because of below>
    S <CR><LF>
    

    然后关闭了连接。

  8. 我建议您需要彻底检查应用程序协议。