socket中的socket recv,错误的行为

时间:2011-11-21 08:08:55

标签: c sockets thread-safety recv

问候!!

我在linux下使用unpv13e库开发为socket服务器,并监听一个端口 将接受3个套接字客户端(最多),每个客户端都有自己的线程....

虽然这3个客户端发送非常快,但socket服务器的recv功能会  接收到的一半字符串来自client1,另一半来自client2, 这很奇怪,因为我认为这3个套接字客户端将在不同的线程中运行, 还有不同的socket id,所以我好奇为什么会这样?让我解释一下 以下代码:

listenfd = Tcp_listen(ipaddr,portno,&addrlen);
cliaddr = Malloc(addrlen);
Signal(SIGINT, sig_int);
for ( ; ; ) {
    clilen = addrlen;
    connfd = Accept(listenfd, cliaddr, &clilen);
    err_msg("id [%05d] conned from %s",connfd,Sock_ntop(cliaddr, clilen));
    Pthread_create(&tid, NULL, &doit, (void *) connfd);
}


void * doit(void *arg)
{
    void web_child(int);
    Pthread_detach(pthread_self());
    web_child((int) arg);
    Close((int) arg);
    printf("thread [%05d] dead...\n",(int) arg);
    return(NULL);
}


void web_child(int sockfd)
{
    int        connfd;
    ssize_t    nread;
    char       line[1024];

    for ( ; ; )
    {
        line[0]=0x00 ;
        if ( (nread = Readline(sockfd, line, 1024)) == 0)
            break;         /* connection closed by other end */
        line[nread-2]=0x00 ;
        if(strncmp(line,"101",3)==0)
            Do101(line) ;
        if(strncmp(line,"201",3)==0)
            Do201(line) ;
        if(strncmp(line,"301",3)==0)
            Do301(line) ;
    }
}

unpv13e库中的readline函数调用recv,并一次检查一个char 直到它是'\ n'并返回,nread通常是315字节左右, 我没有发送这个套接字服务器! 在我看来,web_child函数作为线程运行,具有不同的socketfd, 而line是local var,所以3个不同的客户端不会相互影响, socket client1总是发送字符串以“101”开头,而client2总是发送“201”, client3发送“301”....

但有时我会在Do101(线)中看到一个字符串,其中一半是“101”, 它的后半部分来自client2,它们只是相互影响...... 如果这3个客户非常频繁地发送,可能会发生...不常见, 但它刚刚发生!!

我在代码中遇到了什么错误? recv来自不同的socketid在不同的线程 会相互影响吗?

欢迎任何建议!!谢谢!!

2 个答案:

答案 0 :(得分:2)

这是你正在使用的图书馆吗? https://github.com/k84d/unpv13e/

readline函数似乎不是线程安全的。他们使用静态缓冲区,没有任何东西可以防止并发访问。

答案 1 :(得分:2)

如果Readline()只收到1个字节,则此行失败:

line[nread-2]=0x00 ;

您可以尝试将其更改为:

line[nread-1]=0x00 ;