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

Java客户端无法接收C#服务端TCP响应问题求助

Java与C# TCP通信客户端无法接收响应问题分析

问题概述

首次尝试实现Java客户端与C#服务端的TCP通信,客户端发送消息后服务端能接收并返回响应,但客户端始终无法收到服务端的响应,需分析问题原因及修复方案。

C#服务端代码

public void CreateServer()
{
    Thread thread = new Thread(() =>
    {
        IPAddress addr = IPAddress.Parse(localIP);
        tcpListener = new TcpListener(addr, 5053);
        if (tcpListener != null)
        {
            tcpListener.Start();
            while (!end)
            {      
                TcpClient tcpClient = tcpListener.AcceptTcpClient();
                var ip = ((IPEndPoint)tcpClient.Client.RemoteEndPoint).Address.ToString();
                Console.WriteLine("Client connected from "+ip);   
                NetworkStream clientStream = tcpClient.GetStream();
                StreamReader reader = new StreamReader(clientStream, Encoding.UTF8);
                try
                {
                    string request = reader.ReadToEnd();
                    Console.WriteLine("Message from client: " + request);

                    Byte[] StringToSend = Encoding.UTF8.GetBytes("Server");
                    clientStream.Write(StringToSend, 0, StringToSend.Length);
                    Console.WriteLine("Sending response back");
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                } 
            }
        }
    });
    thread.Start();
}

Java客户端代码

public class TCP {

    private String IP;
    private InetAddress server;
    private Socket socket;

    public TCP(String IP) {
        this.IP = IP;
    }

    protected void runTCP() {
        try {
            server = InetAddress.getByName(IP);
            socket = new Socket(server, 5053);
            System.out.println("Client connected. Listening on port 5053");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void sendMessage(String message) {
        try {
            System.out.println("Sending data...");
            if (socket.isClosed()) socket = new Socket(server, 5053);
            PrintWriter writer = new PrintWriter(socket.getOutputStream());
            writer.print(message);
            writer.flush();
            writer.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void getResponseServer() {
        Thread thread = new Thread() {
            @Override
            public void run() {
                try {
                    System.out.println("Attempting to get response...");
                    if (socket.isClosed()) socket = new Socket(server, 5053);
                    BufferedReader mBufferIn = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                    String mServerMessage = mBufferIn.readLine();
                    System.out.println("Server message: " + mServerMessage);
                } catch (Exception e) {e.printStackTrace();}
            }
        };
        thread.start();
    }
}

运行现象

  • 服务端输出:Client connected from 192.16.... Message from client: Hello Sending response back Client connected from 192.16....
  • 客户端输出:Client connected. Listening on port 5053 Sending data... Attempting to get response...
  • 客户端始终无法收到服务端的响应。

问题原因分析

  1. 客户端发送消息后关闭Socket连接:Java客户端sendMessage方法中调用writer.close(),这会直接关闭Socket的输出流,进而导致整个Socket连接被关闭。当getResponseServer方法尝试读取响应时,原连接已失效,代码中新建的Socket是一个全新的连接,而服务端的响应是发送给第一次建立的连接,新连接自然收不到。

  2. 服务端ReadToEnd()的阻塞逻辑:C#的StreamReader.ReadToEnd()会一直阻塞,直到检测到流的末尾(即客户端关闭输出流或Socket)。这也是服务端能收到"Hello"的原因——客户端关闭输出流触发了ReadToEnd()返回,但此时原连接已关闭,服务端发送的响应无法到达客户端。

  3. 客户端读取响应的阻塞问题:服务端发送的响应"Server"没有换行符,而客户端使用BufferedReader.readLine()读取,该方法会一直阻塞直到读到换行符或流结束。即使新建Socket,服务端也未给这个新连接发送数据,导致读取操作一直卡着。

修复方案

客户端修改

  • 保留Socket连接,不关闭PrintWriter:移除sendMessage中的writer.close(),仅保留flush(),避免关闭Socket连接,同时给发送的消息添加换行符,适配服务端的读取逻辑:
public void sendMessage(String message) {
    try {
        System.out.println("Sending data...");
        if (socket.isClosed()) socket = new Socket(server, 5053);
        PrintWriter writer = new PrintWriter(socket.getOutputStream());
        writer.print(message + "\n");
        writer.flush();
        // 不要关闭writer,避免关闭Socket
    } catch (IOException e) {
        e.printStackTrace();
    }
}

服务端修改

  • 改用ReadLine()读取消息:替换ReadToEnd()为ReadLine(),配合客户端发送的换行符完成读取,同时给响应添加换行符,适配客户端的readLine():
try
{
    string request = reader.ReadLine();
    Console.WriteLine("Message from client: " + request);

    Byte[] StringToSend = Encoding.UTF8.GetBytes("Server\n");
    clientStream.Write(StringToSend, 0, StringToSend.Length);
    Console.WriteLine("Sending response back");
}
catch (Exception e)
{
    Console.WriteLine(e);
}

客户端读取逻辑优化

  • 确保使用同一个Socket读取响应:移除getResponseServer中新建Socket的逻辑,直接使用已建立的连接读取:
public void getResponseServer() {
    Thread thread = new Thread() {
        @Override
        public void run() {
            try {
                System.out.println("Attempting to get response...");
                BufferedReader mBufferIn = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                String mServerMessage = mBufferIn.readLine();
                System.out.println("Server message: " + mServerMessage);
            } catch (Exception e) {e.printStackTrace();}
        }
    };
    thread.start();
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 14:30:16