c - 在 C 中通过 TCP 通信,如何在不知道有关数据的任何先验信息的情况下指示停止为请求调用 read()?

标签 c network-programming blocking readblock

我目前正在用 C 编写一个服务器,该服务器使用 TCP 通过套接字进行通信。客户端应该发送 {filename\n} + {file contents\n} 并且服务器将存储该信息,然后在成功时发送响应。但是,我们不能确定客户端实际上会以结构化协议(protocol)发送正确的信息。

通常在更简单的情况下,我们知道之前要发送的指定字节数,并且可以等到达到该指定数字为止。在这种情况下,我们不这样做,目前代码如下所示:

//buffer is a resize-able array, 
//assume it's correct + don't worry about memory leakage for now
resizeablearray_t *buffer;

char data[255];
char retry = 1; 
while (retry) {
   int bytes = read(socketfd, data, 255);
   if (bytes <= 0) {
      fprintf(stderr, "Error %s\n", strerror(errno));
      return;
   }
   push(buffer, data, bytes);
}

因此,我们遇到了一个大问题:我们如何向 c 中的 read() 函数指示我们已经读取了先前调用的所有信息并且我们不应该再次调用它?

read() 函数会阻塞,直到有字节要通过服务器读取。但是,在我们的模型中,如果由于计数不足而继续尝试读取并且缓冲区中没有任何内容,我们将永远等待。

关于如何在没有传入消息及其结构的任何先验信息的情况下,在另一个 read() 调用之前指示我们可以中断 while 循环并停止尝试从套接字读取的任何想法?

最佳答案

在现代文件传输协议(protocol)中,有文件大小的指示,或者更直接地说,事务有效负载中有多少字节。这允许另一方知道将传送多少字节。如果传送的字节数不足,则读者需要继续阅读。当所有字节都被传送时,就没有您所询问的意义上的“额外”调用。

即使发送方是动态创建数据,因此不知道在事务开始时总共要发送多少字节,它至少可以报告当前发送有多少字节被传递.当它完成时,它可以发送一个最终报告,表明它已完成发送。接收方一直读取直到看到这份最终报告。

如果您使用 recv 调用而不是 read,您将能够传递标志以表明您不希望永远阻塞等待,而是希望是否有任何内容可读的即时状态。但是,这是确定传输是否完成的不可靠方法。发件人可能很慢,文件的其余部分很可能会在一段时间后到达。

关于c - 在 C 中通过 TCP 通信,如何在不知道有关数据的任何先验信息的情况下指示停止为请求调用 read()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53530184/

相关文章:

c - 为什么这个快速排序代码不起作用......(c)

c - 在作为指针传递的结构中使用 strcmp()

json - 用于 C++ 的简单 JSON 解析器/生成器 (Windows VS 2010)

python - 多线程 python 应用程序在运行其线程时挂起

javascript - DHTMLX 调度程序在时间轴上阻止/标记员工时间?

c - 如何在 C 中将文件中的整数 fscanf 到数组中?

C 读取行并对数据排序

c# - TcpClient 已建立,但 TcpClient.getStream() 失败

c - 如何在C中通过系统调用配置accept_local

multithreading - 是否有一种模式可以取消另一个调度队列上的 block ?