从 Socket 接收分块数据到单个缓冲区
我正在尝试使用套接字编写一个简单的 SNPP(简单网络寻呼协议)客户端。 除了服务器之间的小不一致之外,一切似乎都运行良好。
当我发送命令时,我需要读取回复,这通常是单个数据块。 然而,Sprint 的 SNPP 服务器分两部分发送回复。 第一个数据块是状态代码的第一位。 第二块是余数。 例如,当我尝试接收“220 网关就绪”回复时,它会像这样到达:
2
我必须发送另一个空命令来检索其余部分:
20 Gateway ready
目前,我正在使用:
byte[] buffer = new byte[256];
socket.Receive(buffer);
如何确保我收到发出命令后的所有可用数据,而不为每个数据块分配单独的缓冲区?
I'm trying to write a simple SNPP (Simple Network Paging Protocol) client using sockets. Everything seems to be working well, except for a small inconsistency between servers.
When I send a command, I need to read the reply, which is usually a single chunk of data. However, Sprint's SNPP server sends replies in two parts. The first chunk of data is the first digit of the status code. The second chunk is the remainder. For example, when I attempt to receive the "220 Gateway ready" reply, it arrives like this:
2
I have to send another empty command to retrieve the rest:
20 Gateway ready
For the moment, I'm using:
byte[] buffer = new byte[256];
socket.Receive(buffer);
How can I make sure that I receive all of the available data after issuing a command without allocating a separate buffer for each chunk of data?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
对于分块响应,我建议您阅读如下数据:
For chunked responses I would recommend you reading data like this:
尝试检查 Socket.Available 属性以确定是否需要再次调用 Receive。
Try to check Socket.Available property to determine if do you need to call Receive again.
我想我理解你的问题。 Socket.Receive 的重载允许您传递一个整数来指定开始放置数据的偏移位置。 如果您在第一次调用时获得 1 个字节(如您的示例所示),则可以使用偏移量 1 调用此重载并使用相同的缓冲区。
I think I understand your question. This overload of Socket.Receive allows you to pass an integer to specify an offset position to start placing data. If you got 1 byte, on the first call as in your example, you can call this overload with an offset of 1 and use the same buffer.
Socket.Receive
返回一个整数,表示已接收的字节数。 您可以检查这是否为 1,然后再次调用Receive
。Socket.Receive
returns an integer that is the number of bytes that were received. You could check if this is 1 and callReceive
again.所有,
当网络服务器以“块”形式发送数据时,它会在每个块之前加上其长度(作为指示十六进制值的字符串)。
块大小[;块扩展名]
块数据
例如:到块 15 字节:
F;
123456789ABCDEF
从 Socket 接收 HTTP 数据的最大问题是确定要读取多少数据:如果您已接收到所有可用数据并再次调用 Recieve 方法,则 Recieve 方法将阻塞,直到远程套接字发送更多数据,这对于HTTP/1.0 连接永远不会发生。
您需要实现一个围绕套接字的读取器; 它应该将数据接收到缓冲区中,并提供一个“ReadLine”方法来读取缓冲区的内容,直到读取到 13 后跟 10 (CRLF)
All,
When a web-server is sending data in "chunks" it precedes each chunk with it's length (as a string indicating the hex value).
chunk-size[;chunk-extensions]
chunk-data
eg: to chunk 15 bytes:
F;
123456789ABCDEF
The biggest issue with receiving HTTP data from a Socket is determining how much data to read: if you have received all the available data and call the Recieve method again, then the Recieve method will block until the remote socket sends more data, which for a HTTP/1.0 connection will never happen.
You need to implement a reader that wraps around the socket; it should receive data into a buffer, and provide a "ReadLine" method that reads the contents of the buffer until it reads 13 followed by 10 (CRLF)