【问题标题】:Why does the client gets the message only after closing the stream in this TLS connection?为什么客户端只有在关闭此 TLS 连接中的流后才能收到消息?
【发布时间】:2017-06-02 09:19:51
【问题描述】:

我正在尝试在本地网络上建立一个简单的 TLS 连接。客户端仅在关闭输出流(输出)后才会收到我要发送的消息。关闭输出流也会关闭套接字。另一个问题是客户端没有正确编码消息(他得到类似 &��!y�S}y.?'zn:�������zC£Cw8�J��=������ �R��y)

我需要使用输入和输出流来回发送消息。

我使用了来自Oracle's websiteKnockKnockProtocol

    ServerSocket serverSocket = new ServerSocket(PORT_NUMBER);
    Socket clientSocket = serverSocket.accept();

    TlsServerProtocol tlserver = new TlsServerProtocol(clientSocket.getInputStream(),
            clientSocket.getOutputStream(), new SecureRandom());


    tlserver.accept(new MyTlsServer(certificateData));

    try (

        // to send to client
        PrintWriter out = new PrintWriter(tlserver.getOutputStream(), true);
        // to receive from client
        BufferedReader in = new BufferedReader(new InputStreamReader(tlserver.getInputStream()));
        ) {


        String inputLine, outputLine;

        KnockKnockProtocol kkp = new KnockKnockProtocol();
        outputLine = kkp.processInput(null);
        out.println(outputLine);
        out.flush();
        out.close();

        while ((inputLine = in.readLine()) != null) {
            System.out.println("point 2");
            outputLine = kkp.processInput(inputLine);
            out.println(outputLine);
            if (outputLine.equals("Bye."))
                break;
        }


    }
    } catch (IOException e) {
        System.out.println(
                "Exception caught when trying to listen on port " + PORT_NUMBER + " or listening for a connection");
        System.out.println(e.getMessage());
    }


}

客户端代码:

Socket socket = new Socket(hostName, portNumber);
    TlsClientProtocol protocol = new TlsClientProtocol(socket.getInputStream(), socket.getOutputStream(),new SecureRandom());

    // client
    DefaultTlsClient client = new DefaultTlsClient() {
        // getAuthentication should be implemented
        public TlsAuthentication getAuthentication() throws IOException {

            TlsAuthentication auth = new TlsAuthentication() {
                // Capture the server certificate information!

                // Called by the protocol handler to report the server certificate Note: this method is responsible for certificate verification and validation
                public void notifyServerCertificate(org.bouncycastle.crypto.tls.Certificate serverCertificate) throws IOException {
                }

                // Return client credentials in response to server's certificate request
                public TlsCredentials getClientCredentials(CertificateRequest certificateRequest) throws IOException {


                    return null;
                }
            };
            return auth;
        }
    };
    protocol.connect(client);


    try (
            PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
            BufferedReader in = new BufferedReader(
                new InputStreamReader(socket.getInputStream()));
        ) {
            BufferedReader stdIn =
                new BufferedReader(new InputStreamReader(System.in));
            String fromServer;
            String fromUser;

            while ((fromServer = in.readLine()) != null) {
                System.out.println("Server: " + fromServer);
                if (fromServer.equals("Bye."))
                    break;

                fromUser = stdIn.readLine();
                if (fromUser != null) {
                    System.out.println("Client: " + fromUser);
                    out.println(fromUser);
                }
            }
        } catch (UnknownHostException e) {
            System.err.println("Don't know about host " + hostName);
            System.exit(1);
        } catch (IOException e) {
            System.err.println("Couldn't get I/O for the connection to " +
                hostName);
            System.exit(1);
        }

}

【问题讨论】:

  • “客户端只有在关闭输出流后才会收到我要发送的消息” - 如果不关闭输出流会怎样?
  • 如果我不关闭流,什么都不会发生。
  • 您刚刚编辑的客户端代码证明了我的观点。

标签: java sockets ssl


【解决方案1】:

为什么客户端只有在关闭这个tls连接的流后才能收到消息?

因为客户端必须处于仅在流结束时终止的读取循环中,这仅在对等方关闭连接时发生。如果您发布客户端代码会有所帮助,但这是不可避免的。

问题是关闭输出流也会关闭套接字。

这不是“问题”。那是way it works - Javadoc

另一个问题是客户端没有正确获取消息(编码问题)

什么“编码有问题”?如果您有这样的问题,发布它。但是您发布的代码唯一可能发生的事情是readLine() 方法中的SocketException: socket closed

我需要使用输入和输出流来回发送消息。

所以不要关闭它们,如果你不打算得到它,不要在流结束之前阅读。

【讨论】:

  • 很抱歉,我还是不明白。如何让客户端处于读取循环中?当客户收到消息时,他会收到类似这样的消息“Server: &��!y�S}y.?'zn:�R�zC£Cw8�J��=��������R��y "
  • 如何让服务器和客户端处于读取和应答循环中,直到其中一个决定使用某个关键字断开连接(例如“Bye”)?我怎样才能让识别流的结尾?
  • 您已经通过in.readLine()) != null) 识别出流的结尾。不清楚你现在在问什么。
猜你喜欢
  • 1970-01-01
  • 2019-04-01
  • 2020-12-28
  • 2017-05-26
  • 2015-03-28
  • 2021-02-13
  • 2020-08-20
  • 2016-07-26
  • 2016-12-02
相关资源
最近更新 更多