Tcp服务器只接受一个命令。需要刷新recv缓冲区吗?

时间:2016-04-02 12:20:21

标签: sockets tcp

我能够发送命令"插入数据"到tcp服务器,它将执行所谓的。我希望服务器一个接一个地接受多个命令。目前,如果我发送"插入数据"然后按Enter键然后发送" bob"这不应该做什么服务器响应,就像我发送"插入数据"再次。如果您认为我应该发布完整的源代码,请在评论中告诉我。屏幕截图:http://imgur.com/UNRFb5n

#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;
}

2 个答案:

答案 0 :(得分:1)

jsonrpc.ServeConn(ws.UnderlyingConn())
}

在client_message中接收数据后,您正在检查名为message的缓冲区。由于你没有将recv()放入缓冲区,当然它没有改变。

另请注意,如果两个字符串相等,则strcmp()返回0;如果两个字符串不同,则返回非零;你可能在if(strcmp())测试中倒退了(我不确定你想要的行为)。

答案 1 :(得分:0)

由于TCP是八位字节流服务,并且无法发送超过一个字节的应用程序级别消息,因此请发送“插入数据”。从客户端可能导致recv()调用使用以下任何一个加载缓冲区:

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

如果应用程序级别消息不完整,则需要更多调用recv()来接收消息的剩余字节。

请注意,发送'插入数据\ 0'如果recv()碰巧在一次调用中返回所有数据,那么只会在缓冲区中产生一个以null结尾的char数组,这就是“read_size”的原因。 recv()返回的是确定传输二进制数据时加载了多少字节的唯一方法:在这样的缓冲区上使用strXXX调用是UB。您可以使用' read_size'传输文本以确保文本为空终止时,如果空终止符不在缓冲区中则阻止UB:

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

..至少会给你一个' client_message'保证以null结尾,但是无法帮助strcmp()无法识别缓冲区中的部分应用程序级消息。

要传输大于一个字节的应用程序消息,您需要一个基于TCP的协议,它可以解析字节流中的消息。