-1

readシステムコールがデータ全体を読み取ったかどうかを知る必要があります。デフォルトreadでは、バッファにデータがない場合、システム コールはブロックされますが、データが完全に読み取られたことは保証されません。正しい確認方法を教えてください。

man ページでは、readシステム コールは0ファイルの終わりに達したときに戻ると言われていましたが、私もそれを試しましたreadが、まったく戻りませんでし0た。

wr_cnt =write(fd, "AT+CGMI\r", sizeof("AT+CGMI\r"));

  if(wr_cnt<0)
        perror("Write to dev failed");
  else
       printf("No.of bytes written=%d\n",wr_cnt);

  while(1)
  {
      //rd_cnt =read(fd, &str, 1);
      if((rd_cnt =read(fd, &str, 1)) <=0)
    {
            perror("Read to dev failed");
            printf("error no=%d\n",errno);
            break;
    }

        printf("char =%c ->  hex=%x rd_cnt=%d\n",str,str,rd_cnt);
        sleep(3);
        str=0;
 }      

 if(rd_cnt==0)
    printf("EOF met\n");
4

1 に答える 1

2

デフォルトでreadは、実際にファイルの終わりであるか、接続が閉じられていない限り、EOF を示すゼロを返しません。ストリーム接続がまだ開いているが、たまたま利用可能なデータがない場合は、read何かが到着するまで「ハング」します。

これには 2 つの解決策があります。

  1. ファイル記述子をノンブロッキングモードに設定します。データがない場合はreadが返され-1、またはerrnoに設定されます (もちろん、いずれにしても もチェックする必要があります)。入力がブロックされる理由は他にもある可能性があるため、念のために短時間再試行する必要があります。EAGAINEWOULDBLOCKEINTR

  2. select 読む前に使います。コードはもう少し冗長ですが、実行時の効率は向上します。select後続の読み取りがブロックされないことが確実な場合、またはタイムアウトに達した場合にのみ戻ります。ストリーミング データの場合、タイムアウトを「EOF」と解釈できます。複数のストリームから入力を読み取る場合selectは、絶対に必要です。

于 2013-08-23T12:43:38.363 に答える