简体   繁体   English

C#异步客户端-访问字符串冻结接收线程

[英]C# Async Client - Accessing string freezes Receive thread

I am writing a C# client to connect to a Node.JS server. 我正在编写一个C#客户端以连接到Node.JS服务器。 Things were working alright, but at one point the receive function stopped working. 一切正常,但是接收功能在某一时刻停止工作。 I was able to determine that accessing the string received by the client is freezing the thread. 我能够确定访问客户端收到的字符串将冻结线程。 Some code excerpts: 一些代码摘录:

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);
}

This outputs the following when receiving 'OK' from Node.JS: 从Node.JS收到“确定”时,将输出以下内容:

Before string
OK

And the newline isn't even even written by the console, since the system output continues directly after 'OK' on the same line. 而且换行符甚至不是由控制台编写的,因为在同一行中的“ OK”之后,系统输出将直接继续。 Any subsequent receives show nothing. 随后的任何接收都不会显示任何内容。 I have no idea what might have caused this, and I can't seem to find anyone else that has run into this problem. 我不知道可能是什么原因造成的,而且我似乎找不到其他人遇到此问题。

socket.EndReceive returns a value that tells you how many bytes were actually read. socket.EndReceive返回一个值,该值告诉您实际读取了多少字节。 You need to get that value and pass it to the GetString method: 您需要获取该值并将其传递给GetString方法:

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

Otherwise, GetString will try to convert the entire string. 否则, GetString将尝试转换整个字符串。 That's going to give you all manner of garbage. 这将给您各种各样的垃圾。 Your existing call to Trim() is removing the trailing nul bytes that are caused by the way you're currently doing it, but that won't prevent you from getting garbage if you pass a partially-filled buffer to the next call. 您现有的对Trim()调用将删除由您当前执行的方式引起的尾随nul字节,但是如果您将部分填充的缓冲区传递给下一个调用,那将不会阻止您产生垃圾。

That said, I see nothing there that would cause the thing to lock up. 就是说,我在那儿看不到任何东西会导致锁死。 Are you certain that you didn't change some other part of the code, and that is causing the lockup? 你确定你没有更改代码的其他部分, 而且是造成死机?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM