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

Write to file descriptor and immediately read from it

今天我遇到了一些看起来很奇怪的代码,乍一看我并不清楚它的作用。

  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 中说:

 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()?这段代码真是令人难以置信。


编辑: 这是此代码最初来源的完整函数:

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;
}

一般send() and recv() functions are for use with sockets (send: send a message on a socket — recv: receive a message from a connected socket). See also the POSIX description of Sockets

套接字文件描述符是双向的——你可以在上面读写。与管道文件描述符不同,您无法读取您所写的内容。使用管道,写入管道写入端的进程可以从管道的读取端读取它写入的内容——如果另一个进程没有先读取它的话。当一个进程在套接字上写入时,该信息将发送给对等进程并且写入者无法读取。

send(2) 是一个只能与套接字一起使用的系统调用。套接字是一个描述符,允许您使用它发送数据或从远程点(远程套接字)接收数据,远程点可以在不同的计算机上,也可以与您在同一台计算机上。但它的工作原理类似于 phone 行,您发送的内容由您的伙伴接收,而 he/she 发送的内容由您接收。 read(2) 系统调用可以被套接字使用,而 send(2) 不能被文件使用,所以你的示例代码混合了与文件相关的调用和与套接字相关的调用(这并不罕见,因为 read(2)write(2) 都可以与套接字一起使用)

你上面 post 的代码是错误的,因为它盲目地将接收到的缓冲区与 strcmp 函数进行比较,假设它接收到一个空终止字符串。可以这样,但也不可以。

即使发件人(在连接的另一端)同意发送完整的消息,nul 终止字符串。接收方首先要获取接收到的数据量(这是read(2)调用的return值,可以是:

  • -! 表示接收时出现一些错误。连接可以由另一方重置,或者另一方可以在您发送数据时重新启动。
  • 0表示没有更多数据或数据结束(另一方关闭了连接)如果另一方超时并且您也采取了这种情况,则会发生这种情况很多回应。它关闭连接而不发送任何内容。你什么也得不到。
  • n 一些数据,小于缓冲区大小,但包括对等方发送的完整数据包(以及它发送的约定的 nul 字节)。这是唯一可以安全 strcmp 数据的情况。
  • n一些数据,小于缓冲区大小,小于传输的数据。这可能是由于几个数据包中数据的一些数据碎片而发生的。然后你必须再做一次 read 直到你的对等方发送了所有数据。例如,数据包碎片在 TCP 中很自然。
  • n一些数据,小于缓冲区大小,大于传输的数据。发件人在您收到之后进行了另一次传输,并且两个数据包都进入了内核缓冲区。您必须调查这种情况,因为您有一个完整的数据包,并且必须将接收到的其余数据保存在缓冲区中,以供以后处理,否则您将丢失已接收的数据。
  • n 一些数据,缓冲区已满,没有 space 来存储完整的传输数据。您已填满缓冲区,但没有 [=22=] 字符出现...数据包大于缓冲区,您 运行 超出缓冲区 space 并且必须决定要做什么(分配其他缓冲区接收其余数据,丢弃数据,或您决定做的任何事情)这不会发生在您身上,因为您期望一个 1 或 2 个字符的数据包,并且您有 100 个缓冲区,但谁知道...

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

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

注:

由于您没有 post 完整且可验证的示例,因此我无法 post 完整且可验证的回复。

对此深表歉意。