通过 C 中的 TCP 通信,如何在不知道有关数据的任何先验信息的情况下指示停止为请求调用 read()? [英] Over TCP communication in C, how can you indicate to stop calling read() for a request without knowing any prior information about the data?

查看:6
本文介绍了通过 C 中的 TCP 通信,如何在不知道有关数据的任何先验信息的情况下指示停止为请求调用 read()?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am currently programming a server in C that communicates over sockets using TCP. The client is supposed to send {filename } + {file contents } and the server will store that information and then send a response on success. However, we can't be sure the client will actually send the proper information in a structured protocol.

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

Often in simpler situations, we know a specified amount of bytes to be sent before and can wait until that specified number has been reached. In this case, we don't and currently the code looks like this:

//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
", strerror(errno));
      return;
   }
   push(buffer, data, bytes);
}

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

Therefore, we're given a huge problem: how do we indicate to the read() function in c that we've read in all the information on the prior call and we shouldn't call it again?

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

The read() function blocks until there are bytes to be read over the server. However, in our model, if we continue to attempt to read due to short counts and there is nothing left in the buffer, we will wait FOREVER.

关于如何在另一个 read() 调用之前指示我们可以中断 while 循环并停止尝试从套接字读取的任何想法?

Any ideas on how to indicate before another read() call, without any prior information on the incoming message and its structure, that we can break from the while loop and stop attempting to read from the socket?

推荐答案

在现代文件传输协议中,有一个文件大小的指示,或者更直接地,事务的有效负载中有多少字节.这允许对方知道将传递多少字节.如果没有传递足够的字节,阅读器需要继续阅读.当所有字节都被传递时,就您所询问的意义而言,没有额外"的读取调用.

In modern file transfer protocols, there is an indication of the size of the file, or more directly, how many bytes in the payload of the transaction. This allows the other side to know how many bytes will be delivered. If not enough bytes are delivered, the reader needs to keep reading. When all the bytes are delivered, there is no "extra" call to read in the sense you are asking about.

即使发送方动态创建数据,因此在事务开始时不知道总共要发送多少字节,它至少可以报告当前发送中发送了多少字节.当它完成时,它可以发送一个表明它已经完成发送的最终报告.接收者一直阅读,直到看到这个最终报告.

Even if the sender is creating data dynamically, and thus doesn't know how many bytes are going to be sent in total at the beginning of the transaction, it can at least report how many bytes are being delivered in the current send. When it is done, it can send a final report that indicates it is done sending. The receiver reads until it sees this final report.

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

If you use the recv call instead of read, you will be able to pass in flags to indicate that you do not wish to block waiting forever, and instead want an immediate status of whether there is anything left to read. However, this is an unreliable method to determine if the transfer is complete. The sender could just be slow, and the rest of the file may very well come some time later.

这篇关于通过 C 中的 TCP 通信,如何在不知道有关数据的任何先验信息的情况下指示停止为请求调用 read()?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆