2014-03-25 29 views
0

我正在编写一个C#客户端来连接到Node.JS服务器。事情工作正常,但有一点接收功能停止工作。我能够确定访问客户端收到的字符串是冻结线程。一些代码摘录:C#异步客户端 - 访问字符串冻结接收线程

Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
byte[] byteData = new byte[2048]; 

... setup socket connection ... 

socket.BeginReceive(byteData, 0, byteData.Length, 
    SocketFlags.None, new AsyncCallback(OnReceive), null); 

private void OnReceive(IAsyncResult ar) 
{ 
    socket.EndReceive(ar); 

    stringData = Encoding.ASCII.GetString(byteData).Trim(); 

    Console.WriteLine("Before string"); 
    Console.WriteLine(stringData); 
    Console.WriteLine("After string"); 

    // always ready to asynchronously receive 
    socket.BeginReceive(byteData, 0, byteData.Length, 
     SocketFlags.None, new AsyncCallback(OnReceive), null); 
} 

此输出以下自收到时“OK”的Node.js:

Before string 
OK 

而且换行不,甚至连由控制台写的,因为该系统输出继续直接在同一行上的'OK'后面。任何后续接收都不会显示。我不知道可能是什么原因造成的,我似乎无法找到其他人遇到这个问题。

回答

1

socket.EndReceive返回一个值,告诉您实际读取的字节数。您需要获得该值,并将它传递给GetString方法:

int bytesRead = socket.EndReceive(ar); 
stringData = Encoding.ASCII.GetString(byteData, 0, bytesRead); 

否则,GetString会尝试将整个字符串转换。这会给你所有的垃圾。您对Trim()的现有调用将删除当前执行方式导致的尾部nul字节,但如果您将部分填充的缓冲区传递给下一个调用,那么这样做不会阻止您陷入垃圾。

这就是说,我没有看到任何会导致事物锁定的东西。你确定你没有更改代码的其他部分,并且导致了锁定?

+0

是的,我确定它不是代码的另一部分,因为我使用了'git reset --hard HEAD',问题依然存在。这让我怀疑Node.JS方面是否存在这个问题,但我不明白这会对客户端造成怎样的影响。 编辑:使用'bytesRead'修复它。我不知道为什么它以前,而不是现在,但我很感谢解决方案。 – BenJuan26

+0

@ BenJuan26:很高兴解决了你的问题。知道缓冲区内容是很有意思的。我的假设是转换整个2048字符缓冲区导致一些字符导致输出的长时间延迟。例如,如果您创建了一串2048'BEL'字符('chr(7)'),然后输出它,计算机将执行2,048个单独的嘟嘟声。这需要很长时间。 。 。 –