pthread_create только если данные доступны на сокете

У меня есть сервер, который отправляет датаграммы udp клиенту и получает датаграммы NACK от клиента, если пакет потерян. Я хочу создать поток, который будет обрабатывать каждый пакет NACK, но я хочу создать поток, только если у меня есть что-то, чтобы получить от клиента. Для этого я подумал использовать select, если в сокете что-то есть, создайте новый поток и вызовите recvfrom из fucntion. Я определяю структуру timeval и заполняю ее 0, потому что не хочу ждать, я хочу, чтобы в течение всего времени, пока сервер отправлял, выбирал "прослушивание через сокет", но всегда возвращал мне 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;
}

2 ответа

Несколько предложений.

менять if(rv == 1) в if(rv > 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);

Попробуй с этим

По крайней мере, под Linux вам нужно повторно инициализировать struct timeval параметр для select() перед каждым вызовом, как это могло быть изменено предыдущим вызовом select(),

...

while(1)
{
  sendto();

  {
    struct timeval tv = 
    {
      0, 0
    };

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

  ...
Другие вопросы по тегам