我正在尝试创建一个通过套接字进行通信的客户端/服务器应用程序。但是当我收到数据时,它会随机乱搞并且总是(有时)显示正确的数据。我用来接收数据的代码:
private static void ReceiveCallback(IAsyncResult AR)
{
try
{
Socket socket = (Socket)AR.AsyncState;
if (SocketConnected(socket))
{
int received = socket.EndReceive(AR);
byte[] dataBuf = new byte[received];
Array.Copy(_buffer, dataBuf, received);
string text = Encoding.ASCII.GetString(dataBuf);
if (!text.Contains("GET") && !text.Contains("HTTP") && text != null)
{
Console.WriteLine(DateTime.Now.ToString("h:mm:ss tt") + ":" + text);
}
socket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), socket);
}
}
catch
{
}
}
有人能解释我为什么会这样吗?提前谢谢!
答案 0 :(得分:1)
我认为你的套接字是一个TCP套接字,因为你正在处理像HTTP这样的东西。
TCP处理流而不是消息。因此,当您执行读操作时,从流中读取最多_buffer.Length
个字节。这意味着您可以轻松读取响应的一部分 - 或者更确切地说,响应将在多个回调之间分配。当你偶然阅读时,一切都按预期工作。在localhost上进行测试时尤其如此,因为Windows对localhost TCP的处理方式与非localhost情况有很大不同。但是当它不阅读时,text
将不包含整个响应 - 并且您的数据已被破坏。
此外,当received
为零时,表示对方关闭了流,您应该停止BeginReceive
。
答案 1 :(得分:1)
您需要循环接收套接字,直到收到完整的消息。
这也意味着您必须具有应用程序级协议。什么定义了消息?
终止角色?然后循环阅读,直到你得到那个角色。
字符数?然后循环读取,直到你得到那么多字符。
消息前面的消息长度是多少?然后循环,直到你得到足够的字节来获取长度,然后循环,直到你得到整个消息。
答案 2 :(得分:0)
您的套接字代码对我来说很好。 .Net世界中编码格式的字符是“Unicode”,您应该将接收的字节转换为Unicode而不是ASCII:
string text = Encoding.Unicode.GetString(dataBuf);