简单的 echo java 套接字程序对我不起作用

问题描述 投票:0回答:1

所以我有两个线程,一个是服务器套接字,第二个是客户端。服务器使用

readAllBytes()
从客户端读取一些消息,然后使用
write()
返回该消息,然后使用
flush()
。客户端基本上做同样的事情,但顺序相反。这是代码:

package org.example;

import java.io.*;
import java.net.*;

public class Main {
    public static void main(String[] args) {
        new Thread(() -> {
            try (ServerSocket serverSocket = new ServerSocket(8080); 
                 Socket socket = serverSocket.accept();
                 InputStream in = socket.getInputStream(); 
                 OutputStream out = socket.getOutputStream()) {

                System.out.println("SERVER: reading message...");
                byte[] bytes = in.readAllBytes();
                System.out.println("SERVER: message from the client: " + new String(bytes));

                System.out.println("SERVER: sending message back...");
                out.write(bytes);
                out.flush();
                System.out.println("SERVER: message sent back.");

            } catch (Exception e) {
                e.printStackTrace();
            }
        }).start();

        new Thread(() -> {
            try (Socket socket = new Socket("localhost", 8080); 
                 OutputStream out = socket.getOutputStream();
                 InputStream in = socket.getInputStream()) {

                System.out.println("CLIENT: sending message...");
                out.write("hello world".getBytes());
                out.flush();
                System.out.println("CLIENT: message sent.");

                System.out.println("CLIENT: reading response from the server...");
                byte[] bytes = in.readAllBytes();
                System.out.println("CLIENT: response from the server: " + new String(bytes));

            } catch (Exception e) {
                e.printStackTrace();
            }
        }).start();
    }
}

但是这是输出:

SERVER: reading message...
CLIENT: sending message...
CLIENT: message sent.
CLIENT: reading response from the server...

虽然客户端说他发送了消息,但服务器没有回复,我不知道为什么。如果我这样做,让服务器只读取来自客户端的消息并且不发回任何内容,并且我让客户端只发送消息而不回读任何内容:

new Thread(() -> {
            try (ServerSocket serverSocket = new ServerSocket(8080); Socket socket = serverSocket.accept(); InputStream in = socket.getInputStream()) {
                System.out.println("SERVER: reading message...");
                byte[] bytes = in.readAllBytes();
                System.out.println("SERVER: message from the client: " + new String(bytes));

            } catch (Exception e) {
                e.printStackTrace();
            }
}).start();

new Thread(() -> {
            try (Socket socket = new Socket("localhost", 8080); OutputStream out = socket.getOutputStream()) {
                System.out.println("CLIENT: sending message...");
                out.write("hello world".getBytes());
                out.flush();
                System.out.println("CLIENT: message sent");

            } catch (Exception e) {
                e.printStackTrace();
            }
}).start();

一切都会很好:

SERVER: reading message...
CLIENT: sending message...
CLIENT: message sent.
SERVER: message from the client: hello world
java sockets inputstream serversocket outputstream
1个回答
0
投票

readAllBytes
读取所有字节。服务器如何知道“hello world”是客户端要发送的全部数据?它没有,所以它等待更多。
readAllBytes
将读取所有内容,直到流关闭。但是如果你关闭流,你也将关闭套接字,这意味着客户端将无法读取服务器的响应。

所以你需要建立某种方式来指示“消息到此结束”,以便服务器可以停止读取消息,并开始发送响应。这可以是特定字节或特定字节序列。或者,可以使用

readNBytes
让服务器每次仅读取固定数量的字节。

既然您要发送文本,我建议您用真正理解text的东西包装输入/输出流,而不是使用原始字节。例如,您可以使用

Scanner
进行读取,使用
PrintStream
进行写入。然后使用行分隔符作为“消息的结尾”(
println
nextLine
)非常方便。

try (ServerSocket serverSocket = new ServerSocket(8080);
     Socket socket = serverSocket.accept();
     Scanner in = new Scanner(socket.getInputStream());
     PrintStream out = new PrintStream(socket.getOutputStream())) {

    System.out.println("SERVER: reading message...");
    String s = in.nextLine();

    System.out.println("SERVER: message from the client: " + s);

    System.out.println("SERVER: sending message back...");
    out.println(s);
    out.flush();
    System.out.println("SERVER: message sent back.");

} catch (Exception e) {
    e.printStackTrace();
}
try (Socket socket = new Socket("localhost", 8080);
     PrintStream out = new PrintStream(socket.getOutputStream());
     Scanner in = new Scanner(socket.getInputStream())) {

    System.out.println("CLIENT: sending message...");
    out.println("hello world");
    out.flush();
    System.out.println("CLIENT: message sent.");

    System.out.println("CLIENT: reading response from the server...");
    String s = in.nextLine();
    System.out.println("CLIENT: response from the server: " + s);

} catch (Exception e) {
    e.printStackTrace();
}
© www.soinside.com 2019 - 2024. All rights reserved.