首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何读取到缓冲区中保存内容的缓冲区?

如何读取到缓冲区中保存内容的缓冲区?
EN

Stack Overflow用户
提问于 2015-06-02 15:04:56
回答 2查看 96关注 0票数 1

我需要跨服务器发送一个文件,但我需要在响应中添加一个header。我不知道如何解决这个问题,因为我可以将文件读入缓冲区,并使用以下代码一次发送一个缓冲区:

代码语言:javascript
复制
while ((nread = read(in, buffer, sizeof(buffer))) > 0) {
  void *p = buffer;
  while (nread > 0) {
    int nwritten = write(csfd, p, nread);
    if (nwritten <= 0) {
      perror("error while sending the file to the client");
      close(in);
      close(csfd);
    }
    nread -= nwritten;
    p += nwritten;
  }
}
close(in);
close(csfd);

但是,由于我需要发送头部,所以我需要能够以<HEADER>\r\n<DATA-1/33>的形式发送第一个数据块,然后将其写入套接字,就像<DATA-2/33><DATA-3/33><DATA-4/33>等等。

因此,假设我在char header[] = "FOUND 43199 29-33\r\n"中有一个头,如何将它与文件中的第一个数据块一起发送?

也许我可以在复制标头之后从数组的稍后位置开始读取到缓冲区?或者也许有更好的方法?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-06-02 15:14:29

我建议使用填充结构或带有有效负载部分的大型缓冲区:

代码语言:javascript
复制
+------------------------------------+  
|                                    |  
|  +----------+----------+--------+  |  
|  |  Header  |  Payload | Footer |  |  
|  +----------+----------+--------+  |  
|    transmit buffer                 |  
+------------------------------------+  

您可以将传输缓冲区发送出去,但是可以更改页眉、有效负载或页脚,而不必更改发送传输缓冲区的代码。

编辑1:实现

一种实现方法是使用一种结构:

代码语言:javascript
复制
struct Transmit_Buffer
{
  Header  m_header;
  uint8_t m_payload[PAYLOAD_CAPACITY];
  Footer  m_footer;
};

另一个实现是字节数组(uint8_t):

代码语言:javascript
复制
uint8_t transmit_buffer[HEADER_SIZE + PAYLOAD_CAPACITY + FOOTER_SIZE];

您可以按索引引用各节:

代码语言:javascript
复制
const unsigned int header_index = 0U;
const unsigned int payload_begin = header_index + HEADER_SIZE;
const unsigned int footer_begin = payload_begin + PAYLOAD_CAPACITY;  

使用这一结构将是:

代码语言:javascript
复制
Transmit_Buffer buffer;
Send_Data((uint8_t *) &buffer, sizeof(Transmit_Buffer));

使用数组:

代码语言:javascript
复制
Send_Data(&transmit_buffer[0], sizeof(transmit_buffer));

若要更改有效负载,您将只访问有效负载部分:

代码语言:javascript
复制
uint8_t * p_payload = &transmit_buffer[payload_begin];

代码语言:javascript
复制
buffer.m_payload

在本设计中,传输函数不关心缓冲区中的内容,它的目的是传输数据。

您可以添加另一个层来创建页眉和页脚部分,然后传输数据。在这种情况下,有效载荷是无关紧要的,因为它只是简单、乏味的数据。

因此,如果页眉和页脚相同,则编写有效负载部分,然后传输缓冲区。

票数 2
EN

Stack Overflow用户

发布于 2015-06-02 15:35:11

只需发送标题,然后负载通过套接字。

如果您担心您的客户端将不得不进行两次读取而不是一次读取,并且您需要执行一次读取,请尽快重新工作您的客户端,因为TCP不是数据包协议,它是一种流协议,不保留应用程序定义的边界。您应该以这样一种方式编写客户端代码,即使一次只接收一个字节,它也能工作。您必须使用有状态解析器,不要假设客户端可以同时对整个消息进行read(),也不要期望发送方边界被保留。

这意味着您的页眉应该包含有效负载的长度,或者您应该有一个脚注(但在这种情况下,您必须在有效负载中转义这样的结束序列,这有点不方便)。

您不能使用不同的write() 调用来强制应用程序级别的框架!

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30599795

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档