LINUX.ORG.RU

[pthread][c][socket] recvfrom возвращает «bad file descriptor».


0

1

Суть такова: многопоточное приложение, в одном потоке принимаются пакеты, в другом парсится то, что принял первый и отправляется обратно. Все это по udp. В итоге имеем «bad file descriptor» при вызове recvfrom().

int sd;

void *recv_mngr_func(void *arg)
{
    uint8_t buf[sizeof(struct msg)];
    struct sockaddr_in client_addr;
    socklen_t client_addr_len;
    
    ...    

    while(1) {
        ...
        if(recvfrom(sd, buf, sizeof(struct msg), 0, // error
                    (struct sockaddr *) &client_addr, &client_addr_len) < 0) {
            perror("server: recvfrom");
        }
        ...
    }
}

int main(int argc, char **argv)
{
    pthread_attr_t common_attr;
    struct sockaddr_in server_addr;
    
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(6006);
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);

    sd = socket(server_addr.sin_family, SOCK_DGRAM, 0);
    if(sd < 0) {
        perror("server: socket");
        exit(EXIT_FAILURE);
    }

    if(bind(sd, (struct sockaddr *) &server_addr, sizeof(server_addr)) < 0) {
        perror("server: bind");
        exit(EXIT_FAILURE);
    }
    
    pthread_mutex_init(&queue_mngr_mutex, NULL);
    pthread_cond_init(&queue_mngr_cond, NULL);
    
    pthread_attr_init(&common_attr);
    pthread_attr_setdetachstate(&common_attr, PTHREAD_CREATE_JOINABLE);

    pthread_create(&recv_mngr_thread, &common_attr, recv_mngr_func, NULL);
    pthread_create(&queue_mngr_thread, &common_attr, queue_mngr_func, NULL);
    ...
}

У меня в Linux ваш код прекрасно работает. Какая у вас ОС?

AptGet ★★★ ()
Ответ на: комментарий от grouzen
main: sd = 3
Starting recv_mngr_func() thread...
recv_mngr_func: sd = 3
server: recvfrom: Bad file descriptor
zsh: segmentation fault  ./src/server
grouzen ★★ ()
Ответ на: комментарий от grouzen
omich@capella:~$ ./test 
main: sd = 3
recv_mngr_func: sd = 3
main: sendto: test
recv_mngr_func: recvfrom: test
main: sendto: test
recv_mngr_func: recvfrom: test
main: sendto: test
recv_mngr_func: recvfrom: test
main: sendto: test
recv_mngr_func: recvfrom: test
main: sendto: test
recv_mngr_func: recvfrom: test
main: sendto: test
recv_mngr_func: recvfrom: test
^C

Проблема не в этом фрагменте.

AptGet ★★★ ()
Ответ на: комментарий от grouzen

>Ну тогда я даже не знаю, вот ссылка на полную версию кода: https://github.com/grouzen/shooter/blob/develop/src/server.c

Вы же там гнездо закрываете сразу после создания нитей, а набор файловых дескрипторов для процесса общий. С fork() перепутали?

Murr ★★ ()
Ответ на: комментарий от grouzen
    pthread_create(&recv_mngr_thread, &common_attr, recv_mngr_func, NULL);
    pthread_create(&queue_mngr_thread, &common_attr, queue_mngr_func, NULL);

    close(sd); /* <-- Yeah... */
AptGet ★★★ ()
Ответ на: комментарий от Murr

Ну это просто чудо какое-то! Спасибо (%. Вот что значит садиться писать код в 2 часа ночи после пол бутылки горячительного.

grouzen ★★ ()
Ответ на: комментарий от Murr

> Вы же там гнездо закрываете сразу после создания нитей

Гнездо? Что это такое??

anonymous ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.