Многопоточный UDP-сервер / клиент - PullRequest
3 голосов
/ 06 апреля 2011

Я только что создал небольшую надежную передачу файлов с использованием udp, но она обрабатывает только одного клиента.Поэтому я подумал об использовании fork (), чтобы сервер обрабатывал несколько клиентов.Но я не знаю, как поступить.На данный момент я знаю, что мне не нужно менять клиентскую часть, и именно сервер будет выполнять грязную работу.Любая мысль / идеи о том, как решить эту проблему, очень ценится.Ps.вот как я начал:

 void sigchldAction(int sig) {
 while (waitpid(-1, 0, WNOHANG) > 0) {
     ;
 }int main(int argc, char *argv[]) {

 return;
} //This is my function that waits for all the processes 

Вот мой сервер:

int main(int argc, char *argv[]) {
    struct sockaddr_in serv_addr;
    int port_number, socket_fd;
    port_number = atoi(argv[1]);

    signal(SIGCHLD, sigchldAction);

    if ((socket_fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)  exit(EXIT_FAILURE);
    if (setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR,
 (const void *)&optval, sizeof(int)) < 0) exit(EXIT_FAILURE);

    bzero((void *)&serv_addr, sizeof(struct sockaddr_in));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    serv_addr.sin_port = htons(port_number);
    if (bind(socket_fd, (struct sockaddr *)&serv_addr,
         sizeof(struct sockaddr_in)) < 0) exit(EXIT_FAILURE);

    pid_t child_pid;
    while (1) {
    child_pid = fork();

    switch (child_pid) {
        case -1:
            perror("Fork() Failed. \n");
            exit(EXIT_FAILURE);
            break;
        case 0:
            process_request(socket_fd);
            exit(EXIT_SUCCESS);
            break;
        case 1:
            close(socket_fd);
            break;

    } 

}
    close(socket_fd);
exit(EXIT_SUCCESS);
}

Тогда моя функция process_request позаботится о любых поступающих данных.

Ответы [ 2 ]

4 голосов
/ 06 апреля 2011

Если вы используете UDP, у вас нет соединения; это протокол без установления соединения.

Если вы собираетесь разветвляться, вам нужно будет сделать то, что делает ftpd, и сказать удаленному клиенту, чтобы он отправлял разветвленные дочерние пакеты на порт, отличный от исходного (и, конечно, ребенок получал на этот порт ).

1 голос
/ 06 апреля 2011

Вам лучше избегать fork() и просто различать клиентов по их исходному адресу.

Основной подход заключается в том, чтобы взять все переменные, которые в данный момент описывают соединение уровня приложения (например, текущий файл, текущую позицию в файле, адрес клиента), и поднять их в struct. Затем вы создаете один экземпляр этого struct для каждого клиента.

Используйте recvfrom() вместо recv() для прослушивания входящих пакетов. Это предоставит адрес клиента (обратите внимание, что адрес в этом смысле должен включать номер порта клиента) - тогда вы можете найти соответствующий экземпляр для каждого клиента struct.

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