1

我正在尝试使用套接字编写一个简单的 SNPP(简单网络寻呼协议)客户端。一切似乎都运行良好,除了服务器之间的小不一致。

当我发送命令时,我需要读取回复,通常是单个数据块。但是,Sprint 的 SNPP 服务器分两部分发送回复。第一个数据块是状态码的第一位。第二块是剩余部分。例如,当我尝试接收“220 网关就绪”回复时,它是这样到达的:

2

我必须发送另一个空命令来检索其余部分:

20 Gateway ready

目前,我正在使用:

byte[] buffer = new byte[256];
socket.Receive(buffer);

如何确保在发出命令后收到所有可用数据,而不为每个数据块分配单独的缓冲区?

4

5 回答 5

4

对于分块的响应,我建议您阅读这样的数据:

using (var resultStream = new MemoryStream())
{
    const int CHUNK_SIZE = 2 * 1024; // 2KB, could be anything that fits your needs
    byte[] buffer = new byte[CHUNK_SIZE];
    int bytesReceived;
    while ((bytesReceived = socket.Receive(buffer, buffer.Length, SocketFlags.None)) > 0)
    {
        byte[] actual = new byte[bytesReceived];
        Buffer.BlockCopy(buffer, 0, actual, 0, bytesReceived);
        resultStream.Write(actual, 0, actual.Length);
    }

    // Do something with the resultStream, like resultStream.ToArray() ...
}
于 2009-05-03T08:21:59.500 回答
1

尝试检查 Socket.Available 属性以确定是否需要再次调用 Receive。

于 2009-05-03T05:18:37.053 回答
0

我想我理解你的问题。Socket.Receive的这种重载允许您传递一个整数来指定开始放置数据的偏移位置。如果您有 1 个字节,则在您的示例中的第一次调用时,您可以使用偏移量 1 调用此重载并使用相同的缓冲区。

于 2009-05-03T05:28:09.790 回答
0

Socket.Receive返回一个整数,它是接收到的字节数。您可以检查这是否为 1 并Receive再次调用。

byte[] buffer = new byte[256];
int len = socket.Receive(buffer);

if (len == 1)
  socket.Receive(buffer, 1, buffer.Length - 1, SocketFlags.None);
于 2009-05-03T06:23:12.810 回答
-1

全部,

当网络服务器在“块”中发送数据时,它会在每个块之前加上它的长度(作为指示十六进制值的字符串)。

块大小 [;块扩展] 块数据

例如:分块 15 个字节:

F; 123456789ABCDEF

从 Socket 接收 HTTP 数据的最大问题是确定要读取多少数据:如果您已接收到所有可用数据并再次调用 Recieve 方法,则 Recieve 方法将阻塞,直到远程套接字发送更多数据,这对于HTTP/1.0 连接永远不会发生。

您需要实现一个环绕套接字的阅读器;它应该将数据接收到缓冲区中,并提供一个“ReadLine”方法来读取缓冲区的内容,直到它读取 13 后跟 10 (CRLF)

于 2013-08-21T05:33:17.860 回答