【问题标题】:A strange behavior of TCP send functionTCP发送函数的奇怪行为
【发布时间】:2013-10-29 04:24:44
【问题描述】:

我正在写一个关于多线程的TCP连接测试,有一个奇怪的现象我无法解决。

程序很简单。我们有一个服务器要接受,三个客户端要连接。最后,服务端会调用send() 将状态返回给客户端并进行类似的循环。但是很遗憾,当服务端接受大约30000个连接时,就停止返回客户端,客户端就会超时退出。

我尝试增加系统端口范围,减少time-wait秒数,减慢TCP连接速度,但没有奏效并正确关闭了socket。

还有其他原因吗? 客户端代码:

    while ( true )
    /*connect server */
{
    initSocketLocal(&client_addr,0);//
    client_socket = socket(AF_INET,SOCK_STREAM,0);
    if( client_socket < 0)
    {
        printf("Create Socket Failed!\n");
        return -1;    
    }
    if( bind(client_socket,(struct sockaddr*)&client_addr,sizeof(client_addr)))
    {
        printf("Client Bind Port Failed!\n");
        close(client_socket);
        return -1;
    }
    initSocket(&server_addr,DATANODE_PORT_READ,ip);

    if((connect(client_socket,(struct sockaddr*)&server_addr, server_addr_length)) < 0)
    {
        perror ("can not connect to server:");  //find error
        printf("client count is %d...\n", clientCount);
        return -1;

    }
    usleep ( 100000 ) ;
    clientCount++;
    printf("client count is %d...\n", clientCount);

    int length = recv ( client_socket ,res ,sizeof ( res ), 0);
    if (length > 0)
    {
        printf ("recv buf is %s \n", res );
    }
    close(client_socket);
    return 0;
}

并将代码作为流:

while(  true )
    /*wait for connect*/
{
    socklen_t length  =   sizeof (struct  sockaddr );

    printf("listening ..... \n");
    pthread_mutex_lock(&m_read);//lock clifd

    if ((clifd  =  accept(sockRead,( struct  sockaddr * ) & cliaddr, & length)) < 0 )
    {
        perror ("can not accept socket:");
        break;
    }

    printf("Read Accept fd %d\n",clifd);

    pthread_create (&t,NULL,handler,&clifd);

}


void* handler(void*arg)

{
    int fd = *((int *)arg);

    sockCount ++;
    pthread_mutex_unlock(&m_read);
    char  ret [ 10 ];

    printf("accept sock count is :  %d !\n",sockCount);
    usleep ( 100000 ) ;

    strcpy ( ret ,"ok" );
    send ( fd, ret, strlen (ret ), 0);//blocked when sockCount reach to 32571..
    printf ("send ok ..\n");
    close (fd);
    pthread_exit(NULL);

}
~

【问题讨论】:

  • 这个程序很简单,并且及时关闭连接,我添加了端口范围,但它没有做任何事情..
  • 定义“停止返回客户端”。对我来说没有任何意义。你的意思是“停止发送”?而且你必须发布一些代码,无论你认为它多么简单。
  • @user2864740 SO_REUSEADDR 到底和它有什么关系?
  • @EJP 是的,当服务器总共达到 32571 个连接时,它停止向客户端发送返回消息..我会发布我的代码。谢谢。
  • 如果您修复了错误处理以便实际存在一些错误,您可能希望发现正在发生的事情。如果这些套接字函数中的任何一个返回-1,您应该调用perror() 或打印一个包含适当strerror 值的字符串。目前只是一个猜谜游戏。

标签: multithreading sockets tcp


【解决方案1】:

您可能已达到最大连接数。在给定端口上,从客户端到服务器的连接限制为 64K。也可以限制防火墙中的连接数。此外,您可以尝试在每个连接之间放置 5 毫秒(左右)的暂停。

【讨论】:

  • 似乎端口和连接的数量不是限制因素,因为我修改我的程序每 0.01 秒接受一次,客户端每 0.01 秒开始连接一次,也就是说每秒总共有 300 个连接。
  • 这个建议不能解决问题。这似乎是发送问题,而不是连接问题,而且无论如何 30000 远小于 3 x 65535。
【解决方案2】:

除了在 handler() 中的 sockCount 之外,还要打印 fd 值,您正在接近 32k。 'ulimit -n' 对文件描述符的数量显示什么?

您在 handler() 中有一个竞争条件,它会提前解锁互斥锁,从而允许其他线程在 fd 仍在使用时对其进行修改。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-05-22
    • 1970-01-01
    • 2019-06-03
    • 2011-06-14
    • 2020-01-31
    • 2014-05-24
    • 1970-01-01
    • 2023-03-24
    相关资源
    最近更新 更多