UDP を使用する信頼性の高いファイル転送プログラムに取り組んでいます。(コンピュータ ネットワーキングのコースの場合。)
私の質問はこれです-まあ、このシナリオを考えてください:
送信者には、(たとえば) 送信する 12 バイトのデータがあります。したがって、送信者は次の呼び出しを実行します。
sendto(fd, &buf, 12, 0, (struct sockaddr *)&cliaddr,sizeof(cliaddr));
これにより、信頼できない方法で 12 バイトのデータが送信されます。このデータの最初の 4 バイトはたまたま「メッセージ長」フィールドです。この場合、最初の 4 バイトの値は 0x0000000C になる可能性があります。
受信者は、recvfrom() を使用して最初の 4 バイトを読み取りたいと考えています。セグメント サイズが 12 バイトであることを確認して、残りの 8 バイトを読み取ります。したがって、レシーバーは次のようになります。
/* read the segment size */ recvfrom(sockfd,&buf,4,0,(struct sockaddr *)&cliaddr,&len); /* do some arithmetic, use bzero(), etc */ /* read the rest of the data */ recvfrom(sockfd,&buf,8,0,(struct sockaddr *)&cliaddr,&len);
このコードを実行すると、最初の 4 バイトは問題なく受信できます。しかし、残りのデータを取得しようとすると、そのデータが失われたようです。私の出力では、ガベージが表示されています。次の12 バイトの一部のように見えますが、送信者は sendto() を行っています。
これは予想される動作ですか?つまり、1 回の recvfrom() 呼び出しで送信されたすべてのデータを読み取れない場合、そのデータ (残りの 8 バイト) が利用可能であるという保証はありませんか?
セグメント ヘッダー (サイズを含む) を送信し、その後にペイロードを送信する標準的な方法は機能しないようです。これは、ヘッダー情報のみを含む 2 つのセグメントと、ペイロードを含む 2 番目のセグメントを送信する必要があるということですか? それとも、これらのシステムコールを間違って使用しているだけですか (または、欠落しているフラグまたは setsockopt() がありますか?)