循环时recv()函数如何工作?

时间:2014-11-29 18:57:19

标签: c sockets client-server server recv

我在MSDN中读到了send()和recv()函数,有一点我不确定我理解。

如果我发送一个大小为256的缓冲区,并接收前5个字节,那么下次调用recv()函数时,它会指向第6个字节并从那里获取数据?

例如:

char buff[256];
memcpy(buff,"hello world",12);
send(sockfd, buffer, 100) //sending 100 bytes

//server side:
char buff[256];
recv(sockfd, buff, 5) // now buffer contains : "Hello"?
recv(socfd, buff,5) // now I ovveride the data and the buffer contains "World"?

谢谢!

2 个答案:

答案 0 :(得分:3)

在C中从TCP接收循环缓冲区的正确方法如下:

char buffer[8192]; // or whatever you like, but best to keep it large
int count = 0;
int total = 0;

while ((count = recv(socket, &buffer[total], sizeof buffer - count, 0)) > 0)
{
    total += count;
    // At this point the buffer is valid from 0..total-1, if that's enough then process it and break, otherwise continue
}
if (count == -1)
{
    perror("recv");
}
else if (count == 0)
{
    // EOS on the socket: close it, exit the thread, etc.
}

答案 1 :(得分:2)

您错过了主要细节 - 使用了哪种套接字以及请求的协议。使用TCP,数据是八位字节粒度,是的,如果发送了256个字节并且您只读取了5个字节,则休息251将在套接字缓冲区中等待(假设缓冲区较大,对于任何非嵌入式系统都是如此)并且您可以在下一个recv()上获取它们。使用UDP并且没有MSG_PEEK时,单个数据报的其余部分将丢失,但是,如果指定了MSG_PEEK,则下一个recv()将从一开始就给出数据报。使用SCTP或其他“顺序数据包”协议AFAIK,可以获得与UDP相同的行为,但我不确定Windows实现细节。