【问题标题】:queueing recv in server connection在服务器连接中排队接收
【发布时间】:2011-12-20 11:02:17
【问题描述】:

情况:我正在用 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
    }
}

【问题讨论】:

  • recv 是否应该读取 '(sizeof buf)-1' 以便为终止 null 留出空间? mystruct 是 malloced,我猜?您没有定义“行”是什么,但通常在一秒钟内(甚至 100 毫秒)写 10 行文本很慢 - 您的 recv() 循环应该很容易跟上这一点,(除非有数百个同时繁忙的客户端连接)。

标签: c sockets queue recv


【解决方案1】:

您不需要对来自客户端的数据进行“排队”。 因为 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

【讨论】:

  • 傻我;我从没想过发件人可能会在每行之后附加'\0'。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-07-23
  • 2015-12-24
  • 1970-01-01
  • 2018-10-09
  • 2013-02-12
  • 2015-03-31
  • 1970-01-01
相关资源
最近更新 更多