Принять несколько последовательных подключений к сокету - PullRequest
4 голосов
/ 22 марта 2011

У меня есть прослушиватель, который передает произвольные данные, HTTP-запросы, в сетевой сокет, который затем доставляется по TCP.Это отлично работает для первого запроса, но слушатель не принимает последующие новые запросы.

Мой вопрос:

Если у меня есть sock=accept(listener,(struct addr *)&sin, &sinlen);, то, основываясь на ссылке на функцию сокета, слушательсокет остается открытым, и я должен иметь возможность повторно вызывать accept() любое количество раз для последующих запросов.Это правильно?Если да, то может ли кто-нибудь более знакомый с программированием сокетов, чем я, объяснить, как может выглядеть этот код?

Ответы [ 3 ]

9 голосов
/ 22 марта 2011

Да, вы можете accept() много раз на слушающей розетке.Чтобы обслуживать несколько клиентов, вам нужно избегать блокирования ввода-вывода - то есть вы не можете просто читать из сокета и блокировать до тех пор, пока не поступят данные. Существует два подхода: вы можете обслуживать каждого клиента в его собственном потоке (или егособственный процесс, используя fork() в системах UNIX), или вы можете использовать select().Функция select() - это способ проверить, доступны ли данные для любой группы файловых дескрипторов.Он доступен как в UNIX, так и в Windows.

6 голосов
/ 22 марта 2011

Вот простой пример из Руководства Beej по сетевому программированию .

while(1) {  // main accept() loop
    sin_size = sizeof their_addr;
    new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size);
    if (new_fd == -1) {
        perror("accept");
        continue;
    }

    inet_ntop(their_addr.ss_family,
        get_in_addr((struct sockaddr *)&their_addr),
        s, sizeof s);
    printf("server: got connection from %s\n", s);

    if (!fork()) { // this is the child process
        close(sockfd); // child doesn't need the listener
        if (send(new_fd, "Hello, world!", 13, 0) == -1)
            perror("send");
        close(new_fd);
        exit(0);
    }
    close(new_fd);  // parent doesn't need this
}

Дочерний процесс - после fork() - асинхронно обрабатывает связь с accept() далее.соединения в родительском.

0 голосов
/ 22 марта 2011

Да, у вас есть правильная общая идея.

В то время как мое программирование сокета C немного устарело, вызов accept на серверном сокете устанавливает канал связи обратно на сторону клиента сокета.При вызове подтверждения при последующих попытках подключения будет настроено несколько каналов сокетов.

Это означает, что следует позаботиться о том, чтобы не перезаписывать одну общую структуру данными определенного подключения, но это не похоже на то, чтоошибка, которую вы будете подвержены.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...