2016-04-02 1 views
0

"データを挿入する"というコマンドをtcpサーバに送ることができます。これは、想定していることを行います。私は、サーバーが複数のコマンドを順番に受け取るようにしたいと思います。現時点では、私は "データを挿入"を送信し、Enterキーを押し、 "データを挿入"を送信した場合のようにサーバーが応答する何もすべきではない "ボブ"を送信します。あなたは、私は完全なソースコードを投稿する必要があると思うなら、最大私はコメントで知らせて...スクリーンショット:http://imgur.com/UNRFb5nTcpサーバは1つのコマンドだけを受け取ります。 recvバッファをフラッシュする必要がありますか?

#define buf 2000 
void *connection_handler(void *socket_desc) 
{ 
    //Get the socket descriptor 
    int sock = *(int*)socket_desc; 
    ssize_t read_size; 
    char *message , client_message[buf]; 
    //char *contents; 
    //contents = "hello"; 
    //strcpy(mess,contents); 
    //Send some messages to the client 
    message = "Greetings! I am your connection handler\n"; 
    write(sock , message , strlen(message)); 

    message = "Now type something and i shall repeat what you type \n"; 
    write(sock , message , strlen(message)); 

    //Receive a message from client 
    while((read_size = recv(sock , client_message , buf , 0)) > 0) 
    { 
     //write(sock , client_message , strlen(client_message)); 
     char start_char[] = "start"; 
     char insert_demo_char[] = "insert_demo"; 
     char *inserting = "Inserting Data\n"; 
     char *complete = "Task Complete\n"; 
     if(strcmp(message, start_char)) 
     { 
      printf("Starting...\n"); 
      //start(); 
      //printf("it works"); 
      //fflush(stdout); 
     } 
     if(strcmp(message, insert_demo_char)) 
     { 
      write(sock , inserting , strlen(inserting)); 
      printf("Inserting data\n"); 
      insert_demo(); 
      write(sock, complete, strlen(complete)); 
      printf("Finished Inserting Data\n"); 
     } 
    } 
    if(read_size == 0) 
    { 
     puts("Client disconnected"); 
     fflush(stdout); 
    } 
    else if(read_size == -1) 
    { 
     perror("recv failed"); 
    } 

    //Free the socket pointer 
    free(socket_desc); 

    return 0; 
} 

答えて

1
while((read_size = recv(sock , client_message , buf , 0)) > 0) 
{ 
    [...] 
    if(strcmp(message, start_char)) 

あなたはclient_messageにデータを受信した後、あなたの代わりにメッセージをという名前のバッファをチェックしています。あなたはそのバッファにrecv()していないので、もちろん変更されていません。

また、strcmp()は、2つの文字列が等しい場合は0を返し、2つの文字列が異なる場合は0以外を返します。あなたはif(strcmp())のテストでそれを後方に持っているかもしれません(あなたが意図した振る舞いがわかりません)。

+0

いずれの場合でも、client_messageはヌルで終了するとは保証されていないため、strcmp()を使用するとUBになります。 –

+1

また、受信テキスト行が複数のrecv()呼び出しで複数の部分で受信された場合、プログラムは正しく動作しません。 –

0

TCPサービスをストリーミングオクテットで、1つのバイトよりも長いアプリケーションレベルのメッセージを送信することはできませんので、クライアントからの「データの挿入」を送信することのいずれかでバッファを読み込むのrecv()の呼び出しをもたらすことができる:

i 
in 
ins 
inse 
inser 
insert 
insert 
insert d 
insert da 
insert dat 
insert data 

アプリケーションレベルのメッセージが不完全な場合は、メッセージの残りのバイトを受信するためにrecv()を呼び出す必要があります。

recv()が1回の呼び出しですべてのデータを返すと、 'insert data \ 0'はバッファ内にヌル終了文字配列を返すことに注意してください。なぜなら、recv ()は、バイナリデータを転送するときに読み込まれたバイト数を判別するための方法です。このようなバッファでstrXXXを使用するのはUBです。 NULL終端がバッファにない場合ので、UBを防止し、テキストが終了nullであることを確認するために、テキストを転送するときは、「read_size」を使用することができます。

while((read_size = recv(sock , client_message , buf-1 , 0)) > 0) 
client_message[read_size]:=\0; 

は..will少なくともそのあなたの「client_message」を与えますstrcmp()がバッファ内の部分的なアプリケーションレベルのメッセージを特定できない場合は役に立ちませんが、NULLで終了することが保証されています。

1バイトを超えるアプリケーションメッセージを転送するには、TCPの上にバイトストリームからメッセージを解析できるプロトコルが必要です。

+0

あなたの答えをありがとう。あなたは私がこれを修正する方法を学ぶことができるように勉強することができる任意のオンライン書籍の知っていますか? –