首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >写入文件描述符并立即从中读取

写入文件描述符并立即从中读取
EN

Stack Overflow用户
提问于 2020-04-18 05:20:21
回答 2查看 1K关注 0票数 1

今天,我遇到了一些看上去很奇怪的代码,乍一看,它的作用并不明显。

代码语言:javascript
复制
  send(file_desc,"Input \'y\' to continue.\t",0x18,0);
  read(file_desc,buffer,100);
  iVar1 = strcmp("y",(char *)buffer);
  if (iVar1 == 0) {
    // some more code
  }

似乎正在将文本字符串写入文件描述符。然后,它立即将该文件描述符读入缓冲区。并比较写入缓冲区的文本是否为"y"

我的理解是(如果我错了,请纠正我),它将一些数据写入文件描述符,这是一个文本字符串,然后文件描述符充当您写入的任何东西的临时存储位置。然后,它将数据从文件描述符读取到缓冲区中。它实际上是--相同的文件描述符。它似乎是一种使用文件描述符将数据从文本字符串复制到缓冲区的原始方式。为什么不直接使用strcpy()呢?

将什么用例写入文件描述符,然后立即从中读取?使用文件描述符复制数据似乎是一种复杂的方法。或者我对这段代码的理解不够好,send()read()的这个序列做了什么?

假设这段代码使用文件描述符将文本字符串"Input \'y\' to continue.\t"复制到缓冲区中,为什么要将其与字符串"y"进行比较?每次都应该是假的。

我假设写入文件描述符的任何数据都将保留在该文件描述符中,直到从该文件描述符读取为止。因此,在这里,似乎使用send()将字符串写入,而read()用于将其读回。

man send中,它说:

代码语言:javascript
复制
 The only difference between send() and write(2) is the presence of flags.  With a zero
       flags argument, send() is equivalent to write(2).

他们为什么要用send()而不是write()呢?这段代码简直令人难以置信。

编辑:,这是该代码最初来自的完整函数:

代码语言:javascript
复制
void send_read(int file_desc)

{
  int are_equal;
  undefined2 buffer [8];
  char local_28 [32];

                    /* 0x6e == 110 == 'n' */
  buffer[0] = 0x6e;
  send(file_desc,"Input \'y\' to continue.\t",0x18,0);
  read(file_desc,buffer,100);
  are_equal = strcmp("y",(char *)buffer);
  if (are_equal == 0) {
    FUN_00400a86(file_desc,local_28);
  }
  else {
    close(file_desc);
  }
  return;
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-04-18 05:43:37

send()recv()函数用于套接字(send__:在套接字上发送消息- recv__:从连接的套接字接收消息)。还请参阅插座的POSIX一般描述。

套接字文件描述符是双向的-您可以对它们进行读写。与管道文件描述符不同,您无法阅读所写的内容。有了管道,写入管道写入端的进程可以读取管道读取端所写的内容--如果另一个进程没有先读取它。当进程在套接字上写入时,该信息将传递给对等进程,写入者无法读取该信息。

票数 0
EN

Stack Overflow用户

发布于 2020-04-18 17:19:20

send(2)是一个只能与套接字一起使用的系统调用。套接字是一种描述符,允许您使用它从远程点(远程套接字)发送数据或接收数据,这些数据可以在不同的计算机上或与您相同的计算机上接收。但这就像电话线一样,你发送的东西是由你的伙伴接收的,他/她发送的东西是由你接收的。read(2)系统调用可以由套接字使用,而send(2)不能用于文件,因此示例代码将与文件相关的调用与与套接字相关的调用混合使用(这并不少见,因为read(2)write(2)都可以用于套接字)

上面您发布的代码是错误的,因为它假定接收到了一个以空结尾的字符串,因此它盲目地将接收到的缓冲区与strcmp函数进行比较。情况可以是这样,但也不能。

即使发送方(连接的另一端)同意发送完整的消息,nul也会终止字符串。接收方必须首先获得接收的数据量(这是read(2)调用的返回值,可以是:

  • -!表示接收时出现了一些错误。连接可以由另一方重置,也可以在发送数据时重新启动。
  • 0表示没有更多的数据或数据的结束--(另一方关闭了连接)--这可能发生在另一方有超时而您需要太多时间响应的情况下。它不发送任何信息就会关闭连接。你什么也没收到。
  • N一些数据,小于缓冲区大小,但包括对等方发送的完整数据包(以及它发送的一致nul字节)。这是您可以安全地对数据进行strcmp的唯一情况。
  • N一些数据,小于缓冲区大小,小于传输的数据。这可能是由于几个数据包中的一些数据碎片造成的。然后,您必须执行另一个read,直到您有您的同级发送的所有数据。例如,数据包碎片在TCP中是很自然的。
  • N一些数据,小于缓冲区大小,比传输的数据多。发送方在接收到的数据包之后执行另一次发送,两个数据包都进入内核缓冲区。您必须调查这种情况,因为您有一个完整的数据包,并且必须将接收到的其余数据保存在缓冲区中,以便以后进行处理,否则您将丢失已经接收到的数据。
  • N个数据,完全填充缓冲区,没有空间存储全部传输的数据。你填补了缓冲区,没有\0字符来.数据包大于缓冲区,您将耗尽缓冲区空间,必须决定要做什么(分配其他缓冲区以接收其余的缓冲区,丢弃数据,或您决定做的任何事情),这不会发生在您身上,因为您期望一个1或2个字符的数据包,并且您有一个100的缓冲区,但是谁知道.

至少,作为最低限度的安全网络,您可以这样做:

代码语言:javascript
复制
  send(file_desc,"Input \'y\' to continue.\t",0x18,0);
  int n = read(file_desc,buffer,sizeof buffer - 1);  /* one cell reserved for '\0' */
  switch (n) {
  case -1: /* error */
      do_error();
      break;
  case 0: /* disconnect */
      do_disconnect();
      break;
  default: /* some data */
      buffer[n] = '\0';  /* append the null */
      break;
  }
  if (n > 0) {
      iVar1 = strcmp("y",(char *)buffer);
      if (iVar1 == 0) {
        // some more code
      }
  }

注意:

由于您没有发布完整和可验证的示例,所以我无法发布完整和可验证的响应。

我对此表示歉意。

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

https://stackoverflow.com/questions/61284564

复制
相关文章

相似问题

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