C语言 如何接收工作在套接字编程?



我试图在高水平上理解recv()。recv以块为单位接收数据;但我还是不明白它到底是怎么处理的。例子:

char buffer[1000]; 
int received= recv(sock, buffer, sizeof(buffer), 0)

这是否意味着如果我收到大量文件,缓冲区,如果通过袜子可能例如反映连接存储500字节接收的变量,然后在一个循环中得到另一个300字节,和所有800字节的数据将存储在缓冲区的循环(迷失在接收到的变量,除非占了),还是缓冲需要一个指针来跟踪它最后收到的数据存储在下一代?

recv没有上下文。它只知道它有一些地址(指针)要写入和一些最大大小-然后它会尝试这个。它总是以给定的地址开始书写。例如,如果希望在先前接收到的数据之后添加数据,可以简单地将指针指向先前数据之后的位置,而不是缓冲区的开始。当然,应该调整允许读取的最大大小,以防止缓冲区溢出。

您问"recv()是如何工作的?",因此有必要简要地研究一下一个更简单的函数,它基本上做同样的事情——read()

recv()的作用方式与read()的作用方式大致相同。主要的区别是recv()允许你在最后一个参数中传递标志——但是你并没有使用这些标志。

我的建议是-在尝试使用recv()从网络套接字读取之前-在纯文本文件上练习使用read()

两个函数都返回读取的字节数——除非发生错误,在这种情况下它们将返回-1。您应该经常检查这种情况,并适当地处理。

两个函数也可以返回小于请求的字节数。在recv()的情况下——从套接字读取——这可能是因为另一端还没有发送所有需要的数据。在使用read()从文件中读取的情况下,可能是因为您已经到达了文件的末尾。

无论如何……

您将需要跟踪当前偏移在您的缓冲区-并在每次读取时更新它。因此声明一个文件作用域变量offset

static off_t offset; static char buffer[1000];

然后-当你的'循环'正在运行-增加每次读取后的偏移量…

while (1) {
size_t max_len = sizeof(buffer) - offset;
ssize_t count = recv(sock, buffer+offset, max_len, 0);
if (count == -1) {
switch (errno) {
case EAGAIN:
usleep(20000);
break;
default:
perror("Failed to read from socket");
close(sock);
break;
}
}
if (count == 0) {
puts("Looks like connection has been closed.");
break;
}
offset += count;
if (offset >= expected_len) {
puts("Got the expected amount of data. Wrapping up ...");
}
}

指出:

  • 使用这种方法,您需要事先知道预期的数据量,或者使用特殊的分隔符来标记消息
  • 的结束。
  • max_len变量指示缓冲区中剩余的空间-并且(也许不用说)您不应该尝试读取比此
  • 更多的字节
  • recv()命令的目标是buffer+offset-不是buffer
  • 如果recv()返回0,AFAIK这表示另一端已经执行了"有序关机"。
  • 如果recv()返回-1,您确实需要检查返回代码。EAGAIN是非致命的-只是意味着你需要再试一次。

最新更新