Is the received stream from a socket limited to a single send command?(从套接字接收的流是否仅限于单个发送命令?)
问题描述
我目前正在开发一个多线程应用程序,我使用以下(简化)代码接收数据:
private void BeginReceiveCallback(IAsyncResult ar){bytesReceived = this.Socket.EndReceive(ar);byte[] receivedData = new byte[bytesReceived];Array.Copy(buffer, receivedData, bytesReceived);长协议长度 = BitConverter.ToInt64(receivedData, 0);字符串协议 = Encoding.ASCII.GetString(receivedData, 8, (int)protocolLength);IList<对象>发送对象 =ParseObjectsFromNetworkStream(receivedData, 8 + protocolLength);InvokeDataReceived(protocol, sentObjects);}
我发现 receivedData
不仅包含预期数据,还包含更多数据.我怀疑这是后来发送的数据,它与流中的前一个数据混合在一起.
我的问题是,我可以期望将哪些数据存储在此缓冲区中.它可以包含来自客户端的两个不同发送操作的数据吗?在这种情况下,我想我必须想出一个协议来区分从客户端发送的数据消息".一种简单的方法是分别以特定(唯一)字节开始和结束每个流.有没有一种通用的方法来分隔消息?此外,我想这意味着单个接收调用可能不足以从客户端获取所有数据,这意味着我必须循环直到找到结束字节?
TCP/IP 套接字连接由两个独立的流组成:一个传入和一个传出.
这是经常被忽略的 TCP/IP 的关键概念之一.从应用程序的角度来看,TCP/IP 不对数据包进行操作;它在流上运行!
没有发送数据包的方法.API 根本不存在.当您发送数据时,您只需将这些字节放在传出流中.然后从另一端的传入流中读取它们.
例如,一侧可以发送 5 个字节,然后再发送另外 5 个字节.接收端可以接收两批5个字节,或者一次一个,或者一次读取全部10个...
要将传入的字节流拆分为消息,您需要消息框架.通常使用两种解决方案之一.您建议的一种是 delimiter 解决方案,其中 SOT/EOT 字节用于指定消息边界.另一种(我更喜欢)是 length prefix 解决方案,其中消息的长度是消息本身的前缀.
在我的博客上进行了更深入的讨论,以及长度前缀示例代码.p>
I currently work on a multithreaded application where I receive data using the following (simplified) code:
private void BeginReceiveCallback(IAsyncResult ar)
{
bytesReceived = this.Socket.EndReceive(ar);
byte[] receivedData = new byte[bytesReceived];
Array.Copy(buffer, receivedData, bytesReceived);
long protocolLength = BitConverter.ToInt64(receivedData, 0);
string protocol = Encoding.ASCII.GetString(receivedData, 8, (int)protocolLength);
IList<object> sentObjects =
ParseObjectsFromNetworkStream(receivedData, 8 + protocolLength);
InvokeDataReceived(protocol, sentObjects);
}
I'm experiencing that receivedData
contains not only the expected data, but also a lot more. I suspect that this is data sent afterwards that has been mixed in with the previous in the stream.
My question is, what data can I expect to be stored in this buffer. Can it contain data from two different send operations from the client side? In this case, then I suppose I will have to come up with a protocol that can differentiate between the data 'messages' sent from the client side. A simple approach would be to respectively start and end each stream with a specific (unique) byte. Is there a common approach to seperating messages? Furthermore I guess this means that a single receive call might not be enough to get all the data from the client which means I'll have to loop until the end byte was found?
TCP/IP socket connections consist of two independent streams: one incoming and one outgoing.
This is one of the key concepts of TCP/IP that is often missed. From the perspective of the application, TCP/IP does not operate on packets; it operates on streams!
There is no method to send a packet. The API simply does not exist. When you send data, you just place those bytes in the outgoing stream. They are then read from the incoming stream on the other side.
As an example, one side can send 5 bytes and then send another 5 bytes. The receiving side can receive two batches of 5 bytes, or one at a time, or all 10 in a single read...
To split the incoming stream of bytes into messages, you need message framing. One of two solutions is commonly used. The one you suggested is the delimiter solution, where SOT/EOT bytes are used to designate message boundaries. Another one (which I prefer) is the length prefix solution, where the length of the message is prefixed to the message itself.
A more thorough discussion is on my blog, along with sample code for length prefixing.
这篇关于从套接字接收的流是否仅限于单个发送命令?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:从套接字接收的流是否仅限于单个发送命令?
基础教程推荐
- rabbitmq 的 REST API 2022-01-01
- c# Math.Sqrt 实现 2022-01-01
- 有没有办法忽略 2GB 文件上传的 maxRequestLength 限制? 2022-01-01
- MS Visual Studio .NET 的替代品 2022-01-01
- 将 Office 安装到 Windows 容器 (servercore:ltsc2019) 失败,错误代码为 17002 2022-01-01
- 为什么Flurl.Http DownloadFileAsync/Http客户端GetAsync需要 2022-09-30
- 如何激活MC67中的红灯 2022-01-01
- SSE 浮点算术是否可重现? 2022-01-01
- 如何在 IDE 中获取 Xamarin Studio C# 输出? 2022-01-01
- 将 XML 转换为通用列表 2022-01-01