0

重要なのは、4096 バイトを送信するが、約 119 バイトしか送信しないことです。有益な情報を運ぶ。

100 バイトは \r\n\r\n で終わるため、クライアントで \r\n\r\n を読み取ると、その文字列からの情報の受信を停止し、最初からやり直す必要があります。

フラッシュする必要があるのか​​、ソケットを閉じる必要があるのか​​ わかりません...

それらはソケット TCP です。

クライアントで私は:

 buf details[4096];
 strcpy(details,"1");
 strcat(details,"10/04/12");
 strcat(details,"Kevin Fire");
 strcat(detils,"abcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcde\r\n\r\n");
 nbytes_sent = send(sock,(char *)details,sizeof(details),0);

一方、サーバーは...

char buf[20];
memset(buf,'\0',20);

while(!end){
 nbytes_read=recv(sclient,(char *)ress,sizeof(ress),0);

 if(strcmp(ress,"1")==0){
   printf("Details: %s (%i)\n",buf,nbytes_read);
   while(strcmp(buf,"\r\n\r\n") != 0){
     nbytes_read=recv(sclient,(char *)buf,sizeof(buf),0);
     cout.flush();
     printf("Details: %s (%i)\n",buf,nbytes_read);
   }                                     }
   if(strcmp(buf,"\r\n\r\n")==0) printf("The End\n");
   cout.flush();
 }
}

新しい「ress」を読みたいだけで、役に立たない残りのバイトを取得したくありません。

前もって感謝します。

4

4 に答える 4

1

残りのデータを破棄して新しいブロックを読み取りたい場合は、TCPはストリーム指向であり、メッセージの概念がなく、無視したい残りのメッセージがわからないため、TCPでは実行できません。 。あなたが何か他のものを意味するならば、それをもっと説明してください。

nbytes_sent = send(sock,(char *)details,sizeof(details),0);ただし、nbytes_sent = send(sock、(char *)details、strlen(details)、0); `までのデータのみを使用する理由に加えて、\r\n' is important. you can use有効なデータのみを送信し、ネットワーク経由で送信するガベージを削減します。サーバーで最初からやり直すには??

于 2012-10-02T20:38:50.077 に答える
0

私があなたの質問に完全に従っているのかどうかはわかりませんがend=true、受信しているメッセージの終わりを検出するたびに設定できるようです。

char buf[20];
memset(buf,'\0',20);
while(!end)
{
    nbytes_read=recv(sclient,(char *)ress,sizeof(ress),0);
    if(strcmp(ress,"1")==0)
    {
        printf("Details: %s (%i)\n",buf,nbytes_read);
        while(strcmp(buf,"\r\n\r\n") != 0)
        {
            nbytes_read=recv(sclient,(char *)buf,sizeof(buf),0);
            cout.flush();
            printf("Details: %s (%i)\n",buf,nbytes_read);
        }
    }
    if(strcmp(buf,"\r\n\r\n")==0)
    {
        end = true; // <--- This should do it for you, right?
        printf("The End\n");
    }
    cout.flush();
}

ただし、クライアントがまだ接続されていて、ソケットに次のメッセージを書き込んでいる場合は、次のメッセージの読み取りを開始する必要があります。では、メッセージが書き込まれると、クライアントはどうなりますか?次のメッセージの書き込みを開始しますか、それともソケット接続を閉じますか?

さらに、バッファにあるものを取得して、そこからメッセージを作成する必要があります。現在のメッセージが完了したら、次のメッセージのバッファの内容を使用して新しいメッセージを作成することを検討してください。

于 2012-10-02T19:31:24.067 に答える
0

各リクエストが新しいソケットを開くHTTP1.0のようなプロトコルを設計する場合は、十分に読んだ後でソケットを閉じます。

それ以外の場合は、4096バイト全体をスキップするまで読み取りを続ける必要があります。最も簡単な方法は、最初に4096バイトを取得するまで読み取りを続け(ループで呼び出す必要がありrecvます)、次にバッファーの内容を解析することです。繰り返しになりますが、プロトコルを再設計したほうがよい場合があります。

于 2012-10-02T19:32:01.337 に答える
0

私の考えは、最初の x 文字だけを覗き込むことです。4 文字は、予想されるバッファーのサイズである可能性があります。

たとえば、メッセージが次の場合:

(回路図を使用するには) 100 バイトと \r\n\r\n です。100 + 4 ですから 104 です。

文字列の先頭に char(104) をセンティナル値として送信し、その直後に文字列を送信するので、次のように表示されます

char(104)abcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcde\r\n\r\n

次に、recv の peek_MSG 機能を使用して最初の文字を取得し、文字列サイズを作成し、その値のみを読み取り、残ったものはソケット フラッシュ呼び出しによって破棄されます。

于 2012-10-02T22:24:50.177 に答える