Конечная точка транспорта не подключена при чтении

Я пишу сервер POP3, и по какой-то странной причине он работает только на моем компьютере и ни на ком другом. Он просто вышел с ошибкой «Конечная точка транспорта не подключена». Google показывает, что большинство проблем с одним и тем же сообщением об ошибке вызвано передачей идентификатора сокета вместо идентификатора соединения для чтения, но я ничего подобного не делал, и на самом деле я решил проверить, что они разные, что верно каждый раз. время, когда я пытаюсь запустить его.

void pop_protocol(int connection_descriptor){
    pthread_t tid;
    pthread_create(&tid, NULL, pop_worker, (void *) &connection_descriptor);
}

void *pop_worker(void *cd) {
    int connection_descriptor = *((int *) cd);
    socket_write(connection_descriptor, "+OK POP3 server ready\r\n");
}

int sockfd = socket_setup(portno);
while (1) {
    int connection = socket_get_new_connection(sockfd);
    pop_protocol(connection);
}

int socket_setup(int portno){
    int fd = socket(AF_INET, SOCK_STREAM, 0);
    if (fd == -1) {
        fprintf(stderr, "Error: Cannot create socket\n");
        perror("");
        exit(1);
    }

    struct sockaddr_in address;
    address.sin_addr.s_addr = INADDR_ANY;
    address.sin_family      = AF_INET;
    address.sin_port        = htons(portno);

    if (bind(fd, (struct sockaddr *) &address, sizeof(address)) == -1) {
        fprintf(stderr, "Error: Cannot bind socket to port %d\n", portno);
        perror("");
        exit(1);
    }

    if (listen(fd, MAXCONNECTION) == -1) {
        fprintf(stderr, "Error: Cannot listen on port\n");
        perror("");
        exit(1);
    }

    return fd;
}

int socket_get_new_connection(int sockfd){
    struct sockaddr_in address;
    socklen_t addrlen = sizeof(struct sockaddr_in);
    int new_socket = -1;
    int count = 0;
    while (new_socket < 0 && count < ACCEPTCOUNTER) {
        new_socket = accept(sockfd, (struct sockaddr *) &address, &addrlen);
    }

    // Attempt timed out. Exit
    if (count == ACCEPTCOUNTER) {
        fprintf(stderr, "Error: Cannot accept new connections");
        perror("");
        exit(1);
    }

    return new_socket;
}

Буду очень признателен, если кто-нибудь подскажет, как разобраться в проблеме.


person user2350018    schedule 02.06.2013    source источник
comment
int sockfd = socket_setup(portno); while (1) { int connection = socket_get_new_connection(sockfd); pop_protocol(connection); } это где ?   -  person mf_    schedule 02.06.2013
comment
ой извините, это в основном.   -  person user2350018    schedule 02.06.2013


Ответы (1)


Вы передаете указатель на локальную переменную (параметр connection_descriptor) в новый поток. К моменту создания и выполнения потока функция pop_protocol, скорее всего, вернется, а локальная переменная уже недействительна (на самом деле ее значение все еще может существовать по адресу, который был передан новому потоку, но это поведение undefined .)

Попробуйте выделить память для connection_descriptor с помощью malloc, передав эту память (не локальную переменную!) в создаваемый поток и free эту память внутри функции потока после того, как идентификатор сокета будет скопирован в локальную переменную.

person nullptr    schedule 02.06.2013
comment
О, большое спасибо! Это помогло. По какой-то причине я рассматривал эту часть темы и просто не думал смотреть на нее. Самое обидное, что на моем же компе все работало безотказно. Думаю, мне просто придется довольствоваться тем, что в моем компьютере более чем достаточно памяти. - person user2350018; 02.06.2013