簡體   English   中英

寫入文件描述符並立即從中讀取

[英]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() 這段代碼真是令人難以置信。


編輯:這是完整的 function 此代碼最初來自:

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()recv()函數用於 sockets ( send :在套接字上發送消息 - recv :從連接的套接字接收消息)。 另請參閱Sockets的 POSIX 描述。

套接字文件描述符是雙向的——您可以在它們上讀寫。 與 pipe 文件描述符不同,您無法閱讀您寫的內容。 使用管道,寫入 pipe 的寫入端的進程可以從 pipe 的讀取端讀取它寫入的內容——如果另一個進程沒有先讀取它。 當一個進程在套接字上寫入時,該信息會發送到對等進程並且不能被寫入者讀取。

send(2)是一個系統調用,只能與 sockets 一起使用。 套接字是一個描述符,允許您使用它來發送數據或從遠程點(遠程套接字)接收數據,該點可以在不同的計算機上或與您相同的計算機上。 但它就像電話線一樣,您發送的內容由您的伴侶接收,他/她發送的內容由您接收。 sockets 可以使用read(2)系統調用,而文件不能使用send(2) ,因此您的示例代碼將與文件相關的調用與與 sockets 相關的調用混合在一起(這並不罕見,如read(2)write(2)都可以與套接字一起使用)

您在上面發布的代碼是錯誤的,因為它盲目地將接收到的緩沖區與strcmp function 進行比較,假設它收到了一個 null 終止的字符串。 這可能是這種情況,但它也不能。

即使發送者(在連接的另一端)同意發送完整的消息,nul 終止的字符串。 接收方必須首先獲取接收到的數據量(這是read(2)調用的返回值,可以是:

  • -! 表示接收時出現一些錯誤。 連接可以由另一端重置,或者在您發送數據時另一端可能已重新啟動。
  • 0表示沒有更多數據或數據結束(對方關閉了連接) 如果對方超時並且您響應時間過長,則可能會發生這種情況。 它關閉連接而不發送任何內容。 你只是一無所獲。
  • n一些數據,小於緩沖區大小,但包括對等方發送的完整數據包(以及與它一起發送的約定 nul 字節)。 這是唯一可以安全地對數據進行strcmp的情況。
  • n一些數據,小於緩沖區大小,小於傳輸的數據。 這可能是由於多個數據包中數據的某些數據碎片造成的。 然后您必須再次read ,直到您的對等方發送所有數據。 例如,數據包碎片在 TCP 中很自然。
  • n一些數據,小於緩沖區大小,並且大於傳輸的數據。 發送者在您收到的那個之后又進行了一次傳輸,兩個數據包都進入了 kernel 緩沖區。 您必須調查這種情況,因為您有一個完整的數據包,並且必須將接收到的數據的 rest 保存在緩沖區中,以供以后處理,否則您將丟失收到的數據。
  • n一些數據,緩沖區已滿,沒有空間存儲完整傳輸的數據。 您已填充緩沖區並且沒有\0字符來...數據包大於緩沖區,您用完了緩沖區空間並且必須決定做什么(分配其他緩沖區來接收 rest,丟棄數據或其他您決定這樣做)這不會發生在您身上,因為您期望一個包含 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 '\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
      }
  }

筆記:

由於您沒有發布完整且可驗證的示例,因此我無法發布完整且可驗證的回復。

對此我深表歉意。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM