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

TcpClient连接办公服务器后发送数据挂起问题排查求助

排查TCP客户端无法向办公服务器发送数据的问题

从你的描述来看,本地测试完全正常,但连接办公服务器时能正常建立/断开连接,发送数据却挂起且服务器无接收记录,旧Delphi程序却能正常工作,这说明问题大概率出在代码的细节处理上,而非网络层面。结合你提供的代码,我梳理了几个关键排查点:

1. 发送数据的循环逻辑存在明显错误

看你SendButton_Click里的循环代码:

for (int cnt = 0; cnt < SingleSendRichTextBox.Lines.Count() - 1; cnt++)

这个条件会导致最后一行文本完全不会被处理!比如如果文本框有3行内容,Lines.Count()是3,循环只会执行cnt=0和cnt=1,索引为2的最后一行直接被跳过。

而你原本的逻辑是要给最后一行加上结束块标识(char)0x1C,现在这个结束符根本没被加到发送数据里。办公服务器很可能在等待这个结束符才会处理报文,导致服务器一直没收到完整数据,不会回复;同时你的客户端在发送后立刻调用ReadAllBytes(),而NetworkStream.Read()是阻塞方法,会一直等待服务器响应,最终表现为程序挂起。

修复建议:
把循环条件改成包含所有行:

for (int cnt = 0; cnt < SingleSendRichTextBox.Lines.Count(); cnt++)

同时修正最后一行的判断逻辑(现在cnt == SingleSendRichTextBox.Lines.Count() - 1就能正确匹配最后一行)。

2. 断开连接的实现不规范

在DisconnectButton_Click中,你直接操作底层套接字:

m_client.Client.Disconnect(false);
m_client = new TcpClient();

这种方式没有正确释放NetworkStream和TcpClient的资源,可能导致套接字资源泄漏,后续新建的连接可能存在隐性问题。

修复建议:
改用标准的关闭流程:

case ("DisconnectButton"):
    if (m_client.Connected)
    {
        SingleConnectionRichTextBox.Text += "Connection Terminated\r\n";
        ConnectedLightButton.BackColor = Color.Red;
        try
        {
            // 先关闭流,再关闭客户端
            m_client.GetStream().Close();
        }
        catch { }
        m_client.Close();
        m_client = new TcpClient();
    }
    break;

3. 阻塞读取没有超时机制

ReadAllBytes()中的stm.Read()是阻塞调用,如果服务器因为数据不完整等原因不回复,客户端会一直卡在这个方法上,完全失去响应。

修复建议:
给NetworkStream设置读取超时,比如5秒,这样即使服务器没回复,也会抛出超时异常,方便你定位问题:

public void ReadAllBytes()
{
    try
    {
        Byte[] readdata = new Byte[256];
        String responseData = String.Empty;

        NetworkStream stm = m_client.GetStream();
        stm.ReadTimeout = 5000; // 设置5秒超时

        Int32 bytes = stm.Read(readdata, 0, readdata.Length);
        responseData = Encoding.ASCII.GetString(readdata, 0, bytes);
        SingleReplyRichTextBox.Text += responseData + "\r\n";
    }
    catch (Exception err)
    {
        MessageBox.Show(err.ToString());
    }
}

4. 验证发送数据的完整性

建议在WriteBytes方法中添加日志,输出发送的字节数和十六进制格式的数据,和旧Delphi程序发送的内容做对比,确认数据格式(包括起始符、结束符、换行符)完全一致:

public void WriteBytes(Byte[] data)
{
    try
    {
        if ((m_client.Connected)&&(data.Length > 0))
        {
            NetworkStream stm = m_client.GetStream();

            stm.Write(data, 0, data.Length);
            stm.Flush();

            // 添加日志,查看发送的字节详情
            SingleConnectionRichTextBox.Text += $"Sent {data.Length} bytes: {BitConverter.ToString(data)}\r\n";
        }
        else
        {
            MessageBox.Show("Either we are not connected, or there is no data to send!!");
        }
    }
    catch (Exception err)
    {
        MessageBox.Show(err.ToString());
    }
}

总结

最可能导致你当前问题的核心原因是发送数据时遗漏了最后一行,没有加上服务器期望的结束符,导致服务器不处理也不回复,客户端阻塞在读取操作上。先修复循环逻辑的问题,再配合超时和日志排查,应该能解决问题。

内容的提问来源于stack exchange,提问作者D. Haskins

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 10:25:47