1

问候!

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

虽然这 3 个客户端发送速度非常快,但套接字服务器的 recv 函数将接收到一半来自客户端 1 的字符串,另一半来自客户端 2,这很奇怪,因为我认为这 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 ,一次检查一个字符,直到它是一个 '\n' 并返回,nread 通常是 315 字节左右,我在这个套接字服务器中没有发送!在我看来,web_child 函数作为线程运行,具有不同的 socketfd,并且 line 是本地 var,因此 3 个不同的客户端不会相互影响,socket client1 将始终发送以 "101" 开头的字符串,而 client2 始终发送“201”,客户端3发送“301” ....

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

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

欢迎任何建议!谢谢 !!

4

2 回答 2

2

这是您正在使用的库吗? https://github.com/k84d/unpv13e/

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

于 2011-11-21T08:36:03.150 回答
2

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

line[nread-2]=0x00 ;

您可以尝试将其更改为:

line[nread-1]=0x00 ;
于 2011-11-21T08:36:26.287 回答