【发布时间】:2018-05-26 05:38:37
【问题描述】:
这里有一个小实验,我继承并计划重构的代码,但我被一件事难住了。 vb.net 中的那个有效,但c# 中的那个无效。
顺便说一句,BUFFER_SIZE 等于 2048,我知道它有几个问题,但我只能假设我误解了Byte 构造与两种语言之间的相关性:
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();
收到的错误是:
指定的参数超出了有效值的范围。
这发生在netStream.read
嗯,是的,所以Byte 的处理方式不同.. 关注c#版本,改变:
var byteSendBuffer = new Byte[BUFFER_SIZE - 1];
var byteReceiveBuffer = new Byte[BUFFER_SIZE - 1];
到这里:
var byteSendBuffer = new Byte[BUFFER_SIZE];
var byteReceiveBuffer = new Byte[BUFFER_SIZE];
没有错误,但netStream.read 无限期挂起,所以显然没有取回任何数据,对吧?
我试着用:
if(netStream.CanRead()) { ... }
不起作用,仍然挂起。
你能找出原因吗?同样,是的,我知道这很丑陋。我会解决的。
更新
这绝对令人沮丧。我已经为此尝试了许多建议配置的示例。在新的c#(或曾经是)解决方案中,我为 TcpClient 命令添加了一个vb 项目。不管我做什么,它都会无限期地挂在read上,但可以和vb一起使用。
最终更新
嗯,所有这些麻烦和有用的建议,结果这是处理小细节的那些巨大的重大巧合之一,就像我无法访问的另一端的监听服务一样。返回要发送给侦听器的消息的过程返回了不正确的消息,并且侦听器没有响应数据,它只是超时了。如此微小的细节,(如几个字符)很难发现。
【问题讨论】:
-
New Byte[BUFFER_SIZE - 1]相当于 C# 中的new byte[BUFFER_SIZE]。执行GetStream().Read()时可能发生超时? -
正如@TetsuyaYamamoto 评论所建议的,在 VB 中创建数组时需要指定上限,而 C# 需要长度,因此在 C# 中该数字应始终大于 1。
-
@TetsuyaYamamoto - 谢谢。正确,因为我更改了
BUFFER_SIZE,如问题所示。我完全不知道为什么c#仍然无法正常工作。vb版本不会超时吗?必须盯着我的脸。 -
这里没有什么明显的,但有一些常见错误的证据 - 您指的是 messages,但 TCP 不执行 messages。无法保证您对
Read的调用将收到缓冲区的副本,该缓冲区已传递给另一端对Write的单个调用。 TCP 只是一个无穷无尽的字节流,因此任何 特定 读取调用都可能接收(例如)一个缓冲区的一部分,该缓冲区值得在另一端写入的数据,或在 多次在另一端调用Write。 -
NetworkStream.Read()阻塞(“挂起”),直到有数据可供读取。如果它永远不会继续,则意味着端点没有发送任何东西。如果您想确定在实际尝试读取之前是否有要读取的数据,请检查:if(netStream.DataAvailable) { ... }。