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

为何TcpClient代码在VB.NET中正常运行,在C#中却异常?

问题拆解与排查结果

我来帮你理清楚这段TcpClient代码从VB.NET转C#时遇到的问题,以及最终的根因:

背景

接手需要重构的代码时,发现VB.NET版本的TcpClient逻辑能正常运行,但转成C#后出现了连续的问题,一开始我怀疑是两种语言中Byte数组构造的差异导致的,已知BUFFER_SIZE值为2048。

VB.NET 可正常运行的代码

Dim bytesRcvd As Integer = 0
Dim byteSendBuffer As Byte() = New Byte(BUFFER_SIZE - 1) {}
Dim byteReceiveBuffer As Byte() = New Byte(BUFFER_SIZE - 1) {}
Dim receiveMessage As String = Nothing
byteSendBuffer = Encoding.ASCII.GetBytes(sendMessage)
Dim client As System.Net.Sockets.TcpClient = Nothing
Dim netStream As System.Net.Sockets.NetworkStream = Nothing
client = New System.Net.Sockets.TcpClient("localhost", 9060)
netStream = client.GetStream()
netStream.Write(byteSendBuffer, 0, byteSendBuffer.Length)
bytesRcvd = netStream.Read(byteReceiveBuffer, 0, BUFFER_SIZE)
receiveMessage = Encoding.ASCII.GetString(byteReceiveBuffer, 0, bytesRcvd)
netStream.Close()
client.Close()

初始转换的C# 代码(存在问题)

int bytesRcvd = 0;
var byteSendBuffer = new Byte[BUFFER_SIZE - 1];
var byteReceiveBuffer = new Byte[BUFFER_SIZE - 1];
string receiveMessage = null;
byteSendBuffer = Encoding.ASCII.GetBytes(sendMessage);
System.Net.Sockets.TcpClient client = null;
System.Net.Sockets.NetworkStream netStream = null;
client = new System.Net.Sockets.TcpClient("localhost", 9060);
netStream = client.GetStream();
netStream.Write(byteSendBuffer, 0, byteSendBuffer.Length);
bytesRcvd = netStream.Read(byteReceiveBuffer, 0, BUFFER_SIZE);
receiveMessage = Encoding.ASCII.GetString(byteReceiveBuffer, 0, bytesRcvd);
netStream.Close();
client.Close();

问题现象与分析

  1. 第一个错误:参数越界异常
    运行C#代码时,netStream.Read处报错:"Specified argument was out of the range of valid values."
    这是VB.NET和C#数组初始化的核心差异导致的:

    • VB.NET中New Byte(BUFFER_SIZE - 1)创建的是长度为BUFFER_SIZE的数组(括号内是数组的最大索引值)
    • 而C#中new Byte[BUFFER_SIZE - 1]创建的是长度为BUFFER_SIZE - 1的数组(方括号内是数组的实际长度)
      当调用netStream.Read(byteReceiveBuffer, 0, BUFFER_SIZE)时,要求读取最多BUFFER_SIZE个字节,但数组仅能容纳BUFFER_SIZE-1个字节,直接触发了参数越界。
  2. 第二个问题:Read方法无限挂起
    修改C#的Byte数组定义为new Byte[BUFFER_SIZE]后,参数越界的错误消失了,但netStream.Read会无限挂起,哪怕用netStream.CanRead判断也没用。
    这是因为NetworkStream.Read是阻塞式方法——它会一直等待,直到有数据可读或者连接被关闭。CanRead属性仅表示当前流是否处于可读状态,并不代表已有数据到达。

最终根因排查

后来我新增VB项目做对比测试,发现并非C#代码本身的问题——最终排查出,问题出在远端的监听服务:当前程序没有权限访问该服务,导致服务端返回消息异常,最终服务端根本没有响应任何数据,所以Read方法会一直阻塞等待,直到超时。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:40:48