2016-08-30 10 views
4

TCPソケットからデータを取得するために私が使用する読み取り機能が返ってくると誰かが説明してくれますか?TCPソケットのread()はいつ返します

以下のコードを測定システムから読み取るために使用します。このシステムは、15Hzの周波数のデータを配信します。 READ_TIMEOUT_MSの値は200 です。さらにREAD_BUFFER_SIZEの値は40000です。 すべて正常に動作しますが、何が起こるかはread()が1秒間に15回戻り、1349バイトが読み込まれます。

http://www.ibm.com/developerworks/library/l-sockpit/

のInit:バッファが完全に満たされていることを、私が期待していた以下の文書に落とし穴5を読み取ることにより

sock=socket(AF_INET, SOCK_STREAM, 0); 
if (socket < 0) 
{ 
    goto fail0; 
} 

struct sockaddr_in server; 
server.sin_addr.s_addr = inet_addr(IPAddress); 
server.sin_family = AF_INET; 
server.sin_port = htons(Port); 
if (connect(sock,(struct sockaddr *)&server, sizeof(server))) 
{ 
    goto fail1; 
} 

struct timeval tv; 
tv.tv_sec = READ_TIMEOUT_MS/1000; 
tv.tv_usec = (READ_TIMEOUT_MS % 1000) * 1000; 
if (setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(struct timeval))) 
{ 
    goto fail1; 
} 

return true; 

fail1: 
    close(sock); 
    sock = -1; 
fail0: 
    return false; 

読む:

unsigned char buf[READ_BUFFER_SIZE]; 
int len = read(sock, buf, sizeof(buf)); 
if (len <= 0) 
{ 
    return NULL; 
} 

CBinaryDataStream* pData = new CBinaryDataStream(len); 
pData->WriteToStream(buf, len); 
return pData; 

この質問は重複しないことを願っています私が尋ねる前に私が答えを捜したからです。 さらに詳しい情報が必要な場合はお知らせください。

+0

:ここでは、面白いかもしれないいくつかの追加のリンクです。あなたはあなたが望むよりも少ないバイト数を得る準備が必要です。落とし穴5は実際にそれを意味します。この図は1024バイトの読み込みを示していますが、200バイトを返すテキストについての話です。 –

+0

より簡単に制御できるタイムアウトについては、['select'](http://man7.org/linux/man-pages/man2/select.2.html)を調べるとよいでしょう。 – user4581301

+0

@ n.m:このOSの動作を理解しました。しかし、 'read()'の呼び出しが毎回、必要なバイト数のバイトを返すのはなぜだろうかと思います。 – bushmills

答えて

1

Linuxを使用していると思われます。 manpage for read says:バイト数が返される読み取り成功し

(ゼロ端ファイルの を示す)、およびファイル位置はこの数だけ進められます。この数が要求されたバイト数よりも小さい場合、エラーは ではありません。

TCPソケットは、ブロックまたはメッセージ指向のプロトコルではなく、バイトストリームをモデル化します。アプリケーションのバッファで利用可能なデータがあれば、ソケット上でreadを呼び出します。原則として、データはネットワークカードに到着し、カーネル空間に転送され、そこでカーネルとネットワークスタックによって処理されます。最後に、read syscallは、カーネル空間からデータを取得し、それをユーザ空間に転送します。

ソケットから読み取るときは、読み込み可能な任意のバイト数が必要です。読み取りバッファーに何かがあるとすぐに、またはエラーが発生したときに、read呼び出しが返されます。使用可能なバイト数を予測または仮定することはできません。

さらに、OSが中断されているため、何も読み込まずに呼び出しを返すことができます。これは、アプリケーションをデバッグまたはプロファイルするときに非常に頻繁に発生します。アプリケーション層でこれを処理する必要があります。

データレートが高くても待ち時間が短い場合でも、完全な受信者パスは驚くほど複雑です。カーネルお​​よびNICは、例えば、コアに負荷を分散し、局所性を高め、NICへの処理をオフロードします。お使いのOSがそれのように感じる時はいつでもそれを返し

+0

ありがとうございました!はい、Linuxプラットフォームで作業しています。あなたは「読み込みバッファに何かがあるとすぐに読み込み呼び出しが返されます」と言う。これは、私の場合、 'read()'によって返されたバイトが何らかの理由で単純に "一致"することを意味しますか? – bushmills

+1

@bushmills NICからアプリケーションまでのホールのパスを説明する豊富なWebサイトがあります。 http://www.cubrid.org/blog/dev-platform/understanding-tcp-ip-network-stack/。 – Jens

+0

@bushmillsはい、readを呼び出すことで、指定された最大値まで任意のバイト数を取得できます。それは1になる可能性があります。メッセージの予想されるバイト数を受け取るまでループを読み込んでください。 – Jens

関連する問題