[英]recv the first few bytes from a socket to determine buffer size
我正在使用TCP/IP
和sockets
在c++
编写一个分布式系统。
对于我的每条消息,我需要接收前5个字节来了解传入消息的完整长度。
最好的方法是什么?
recv()
仅5个字节,然后再次recv()
。 如果选择此选项,可以安全地假设我将在recv中获得0或5个字节(也就是不编写循环来继续尝试)吗? MSG_PEEK
recv()
较大的缓冲区大小,然后读取前5个字节,然后分配最终缓冲区。 你不需要知道的任何事情。 TCP是一种流协议,在任何给定的时刻,您最多只能获得一个字节或多达几兆字节的数据。 使用TCP套接字的唯一正确方法是循环读取。
char buf[4096]; // or whatever
std::deque<char> data;
for (int res ; ; )
{
res = recv(fd, buf, sizeof buf, MSG_DONTWAIT);
if (res == -1)
{
if (errno == EAGAIN || errno == EWOULDBLOCK)
{
break; // done reading
}
else
{
// error, break, die
}
}
if (res == 0)
{
// socket closed, finalise, break
}
else
{
data.insert(data.end(), buf, buf + res);
}
}
循环的唯一目的是将数据从套接字缓冲区传输到应用程序。 然后,您的应用程序必须独立决定队列中是否有足够的数据,以尝试提取某种更高级别的应用程序消息。
例如,在您的情况下,您将检查队列的大小是否至少为5,然后检查前五个字节,然后检查队列是否包含完整的应用程序消息。 如果不是,则中止,如果是,则提取整个消息,如果从队列的最前面弹出则弹出。
使用具有两种状态的状态机:
第一状态。
在字节到达缓冲区时接收字节。 当有5个或更多字节时,对前5个字节执行检查,并可能处理缓冲区的其余部分。 切换到第二状态。
第二状态。
在字节到达消息末尾时接收并处理它们。
具体回答您的问题:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.