仅当套接字上的数据可用时 pthread_create

Posted

技术标签:

【中文标题】仅当套接字上的数据可用时 pthread_create【英文标题】:pthread_create only if data is available on socket 【发布时间】:2014-05-19 17:28:49 【问题描述】:

如果数据包丢失,我有服务器正在向客户端发送 udp 数据报并从客户端接收 NACK 数据报。我想创建将处理每个 NACK 数据包的线程,但我只想在我从客户端接收到某些东西时才创建线程。为此,我想使用 select ,如果套接字上有东西,则创建新线程并调用 recvfrom 函数。我定义了 timeval 结构并用 0 填充它,因为我不想等待,我希望在服务器发送时一直选择“listening on socket”,但选择总是返回 0 ....是否有任何解决方案不同的想法如何并行发送和接收?

int main (void) 

    struct timeval tv;
    tv.tv_sec = 0;
    tv.tv_usec = 0;

    fd_set readfds;
    FD_ZERO(&readfds);

    // Create the socket
    if((sd = socket (AF_INET, SOCK_DGRAM, 0)) < 0) 
        printf("Server socket could not be created : %s\n",strerror(errno));
        return 0;
    


    // Non-blocking socket
    fcntl(sd,F_SETFL,O_NONBLOCK);

    FD_ZERO(&readfds);
    FD_SET(sd,&readfds);

    //Allow multiple applications to receive datagrams that are destined to the same local port number.
    if(setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) == -1) 
        printf("Setsockopt error: %s", strerror(errno));
        return 1;      
      

    // Initialize the group sockaddr structure with a multicast address of 226.1.1.1 and port 5555. 
    memset((char *) &multiaddr, 0, sizeof(multiaddr));
    multiaddr.sin_family = AF_INET;
    multiaddr.sin_addr.s_addr = inet_addr(IP_GROUP);
    multiaddr.sin_port = htons(PORT_NUM);  

    // Fill the structure udp_srv with informations like multicast address,port number and socket
    strcpy(udp_srv.peer_address,inet_ntoa(multiaddr.sin_addr));
    udp_srv.peer_port = multiaddr.sin_port;
    udp_srv.udp_sd = sd;

    if((fd = open("text.txt",O_RDONLY , 0777))== -1) 
        printf("Error while opening txt file!\n",strerror(errno));
        return 1;       
     else          
        while(1)             
            sleep(1);    
            if((numRead = read(fd,tmp,512)) != 0)                
                tmp[numRead]='\0';
                strcpy(pack.buffer,tmp);
                //function for sending data until EOF !     
                sent = data_sent(udp_srv,&pack);      
             else                
                sent = last_data_sent(udp_srv,&pack);       
                close(sd);
                exit(1);
                     
            rv = select(sd + 1, &readfds, NULL, NULL, &tv);          

            if(rv > 0) 

                // Create a new thread and call recvfrom in nack_processing function !
                if(pthread_create(&cln_thread, NULL, nack_processing, (void *) &arg))
                    printf("Pthrad create errorr\n",strerror(errno));
                    continue;
                
                 
        
    
    return 0;

【问题讨论】:

select 的代码在哪里???? 对不起,我忘记了,上面有问题的代码已更新 【参考方案1】:

一些建议。

if(rv == 1) 更改为if(rv &gt; 0) 并提供一些时间

struct timeval tv;
tv.tv_sec = 5;


fd_set readfds;
rv = select(sd + 1, &readfds, NULL, NULL, &tv);
rv = select(sd + 1, &readfds, (fd_set *)0, (fd_set *)0, &tv);

试试看

【讨论】:

但问题是我无法提供时间,5 秒对于我的实时应用程序来说太多了......我想如果有什么东西,也许 select 可以一直听在服务器一直发送时接收....有什么想法吗? 代码再次更新但不是完整的,因为它有更多的 c 文件和头文件,但你可以从这个 main 中看到这个概念......【参考方案2】:

至少在 Linux 下,您需要在每次调用之前重新struct timeval 参数初始化为 select(),因为它可能已被上一次调用 select() 修改。

...

while(1)

  sendto();

  
    struct timeval tv = 
    
      0, 0
    ;

    rv = select(sd + 1, &readfds, NULL, NULL, &tv);
  

  ...

【讨论】:

以上是关于仅当套接字上的数据可用时 pthread_create的主要内容,如果未能解决你的问题,请参考以下文章

Play Framework,Scala - 仅当有新数据可用时才向客户端发送 websocket 消息

如何等待任何套接字有数据?

仅当 iOS11 可用时才包含类的扩展

套接字中没有可用数据时的异步编程模型

仅当 indexPath 对象可用时,如何在 tableview 单元格上使用标签

仅当有描述可用时才提取类别描述。