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

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

2

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

20 Gateway ready

目前,我正在使用:

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

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

有帮助吗?

解决方案

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

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() ...
}

其他提示

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

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

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

所有

当网络服务器以“块”发送数据时它在每个块之前都有它的长度(作为表示十六进制值的字符串)。

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

例如:to chunk 15 bytes:

F; 123456789ABCDEF

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

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

的方法
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top