Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么客户端仅在关闭此TLS连接中的流后才获取消息?_Java_Sockets_Ssl - Fatal编程技术网

Java 为什么客户端仅在关闭此TLS连接中的流后才获取消息?

Java 为什么客户端仅在关闭此TLS连接中的流后才获取消息?,java,sockets,ssl,Java,Sockets,Ssl,我试图在本地网络上建立一个简单的TLS连接。客户端仅在关闭输出流(out)后才收到我试图发送的消息。关闭输出流也会关闭套接字。另一个问题是,客户机没有正确地编码消息(他得到了类似于&��!Y�S} y.?'zn:�܋�zC英镑Cw8�J��=�������R��y) 我需要使用输入和输出流来来回发送消息 我使用了来自的knockProtocol类 客户端代码: Socket socket = new Socket(hostName, portNumber); TlsClientProto

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

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

我使用了来自的
knockProtocol

客户端代码:

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);
        }

}
为什么客户端仅在关闭此tls连接中的流后才获取消息

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

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

这不是“问题”。这就是问题所在

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

编码有什么问题?如果你有这样的问题,就把它贴出来。但是您发布的代码中唯一可能发生的事情是
readLine()
方法中的
SocketException:socketclosed

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


因此,不要关闭它们,如果您不想得到它,在流结束之前不要读取。

“客户端仅在关闭输出流后才收到我试图发送的消息”-如果你不关闭输出流会发生什么?如果我不关闭流,什么都不会发生。你刚刚编辑的客户端代码证明了我的观点。很抱歉,我仍然不明白。如何使客户机处于读取循环中?当客户端收到消息时,他会收到类似于“服务器:&��!Y�S} y.?'zn:�܋�zC英镑Cw8�J��=�������R��y“我如何使服务器和客户机保持在一个读-答循环中,直到其中一个决定用某个关键字断开连接(例如“再见”)?如何让我识别流的结尾?您已经通过.readLine()中的
识别流的结尾了!=空)
。不清楚你现在在问什么。
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);
        }

}