在服务器连接中排队recv

时间:2011-12-20 11:02:17

标签: c sockets queue recv

情况:我在c中创建一个服务器守护程序,它接受多个同时连接,客户端将向服务器发送数据。我目前将每个客户端连接生成一个新线程。

问题:如果客户端非常快速地发送大量内容(例如,在不到一秒的时间内发送10行数据),服务器将看到前两行,而不是其他行

问题:如何“排队”来自客户端的数据(c中的recv命令)?这是否需要selectpoll?基本上,我想确保任何客户端都可以非常快速地发送大量数据,而不必担心任何内容被丢弃。如何实现这一目标?

示例代码 :(注意:下面的代码显然已被大量修改,特别是通过删除错误检查。我试图修改我的代码,以便使问题/解决方案清晰而不会陷入困境关于不相关部分的语义。请不要在这里遇到任何非标准或缺失的元素。)

//this function handles the threads
void *ThreadedFunction(void *arg) {
    // do some stuff, like: pull vars out of mystruct
    int nbytes;
    char buf[256];
    while(1) {
        if((nbytes=recv(conid, buf, sizeof buf, 0)) <= 0) {
            //handle break in connection
        } else {
            //for this example, just print out data from client to make my point
            buf[nbytes] = 0;
            printf("%s\n",buf);
        }
    }
}

//main just sets up the connections and creates threads
int main(int argc. char *argv[])
{
    // bind(), listen(), etc... blah blah blah

    while(1) {
        conid = accept(...); //get a connection
        // ... build mystruct to pass vars to threaded function ...
        pthread_t p;
        pthread_create(&p,NULL,ThreadedFunction,&mystruct); //create new thread
    }
}

1 个答案:

答案 0 :(得分:0)

您无需“排队”来自客户端的数据。 因为TCP会为您做到这一点。如果服务器太慢而无法为TCP接收缓冲区腾出空间,TCP的流控制甚至会降低客户端的速度。

因此,服务器或客户端的代码可能存在错误。也许客户端在每行的末尾发送'\ 0'。在这种情况下,以下代码不会打印所有行:

if((nbytes=recv(conid, buf, sizeof buf, 0)) <= 0) {
    //handle break in connection
} else {
    //for this example, just print out data from client to make my point
    buf[nbytes] = 0;
    printf("%s\n",buf);
}

如果客户端在每行的末尾发送'\ 0',那么第二行甚至是你看到的最后一行。

例如:

如果客户发送以下行:

"abc\n\0"
"def\n\0"
"ghi\n\0"

TCP通常会使用两个数据包发送,包含以下内容:

"abc\n\0"
"def\n\0ghi\n\0"

服务器通常需要2次recv调用才能接收传入的数据。 所以你的服务器将使用2个打印电话:

printf("%s\n", "abc\n\0\0");
printf("%s\n", "def\n\0ghi\n\0\0");

结果输出为:

abc
def