You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java Socket客户端服务端通信疑问:服务端为何读取输入流而非输出流?

Java Socket客户端-服务端流方向疑问解答

我的代码与疑问

客户端代码NetworkClient

class NetworkClient {
    public static void main(String[] args) {
        Socket socket = null;
        try {
            socket = new Socket("localhost", 3141);

            OutputStream out = socket.getOutputStream();
            PrintStream ps = new PrintStream(out, true);
            InputStream in = socket.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(in));

            ps.println("Es begab sich aber zu der Zeit,");
            System.out.println("client sent: Es begab sich aber zu der Zeit,");

            System.out.println("client received: "+reader.readLine());
        }
        //some other code
    }
} 

服务端代码NetworkServer

public class NetworkServer {
    private final ServerSocket srv;
    public NetworkServer(int port) throws IOException {
        srv = new ServerSocket(port);
    }

    private void connectAndTalk() {
        Socket socket = null;
        try {
            socket = srv.accept();
            communicate(socket);
        }
        // some code
    }

    private void communicate(Socket socket) throws IOException, InterruptedException {
        BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        PrintStream out = new PrintStream(socket.getOutputStream());
        String s;

        do {
            s = in.readLine();
            System.out.println("server received: "+s);

            if(s.equals("Es begab sich aber zu der Zeit,")) {
                TimeUnit.SECONDS.sleep(4);
                out.println("dass ein Gebot ausging vom Kaiser Augustus,");
            }
            // some code

疑问

客户端向自身的输出流写入数据,从自身的输入流读取数据。为什么服务端要读取该Socket的输入流而非输出流?同理,服务端为何向该Socket的输出流写入数据?为什么不能像下面这样实现?

private void communicate(Socket socket) throws IOException, InterruptedException {
    BufferedReader in = new BufferedReader(new InputStreamReader(socket.getOutputStream()));
    PrintStream out = new PrintStream(socket.getInputStream());

核心解释

Socket的输入/输出流是相对于当前进程定义的,和对面进程的流是镜像对称的:

  • 对客户端进程来说:
    • socket.getOutputStream():是客户端往服务端发送数据的通道——客户端写在这里的内容,会传输到服务端
    • socket.getInputStream():是客户端接收服务端数据的通道——服务端发来的内容,客户端从这里读取
  • 对服务端进程来说:
    • 当通过server.accept()拿到与客户端配对的Socket后,这个Socket的流方向和客户端完全对应:
      • 服务端的socket.getInputStream():对应客户端的OutputStream——客户端写的数据,会从服务端的这个输入流里读出来
      • 服务端的socket.getOutputStream():对应客户端的InputStream——服务端写在这里的内容,会传输到客户端的输入流供其读取

如果像你写的那样反过来用,完全没法完成数据交互:

  • 服务端读socket.getOutputStream():这个流是服务端自己用来发数据的通道,里面没有客户端传来的内容,根本读不到有效数据
  • 服务端往socket.getInputStream()里写:这个流是服务端自己用来收数据的通道,写在这里的内容传不到客户端,客户端也读不到任何内容

内容的提问来源于stack exchange,提问作者Turtle

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 12:57:47