UDP Socket программирование - форк-сервер при получении - PullRequest
0 голосов
/ 22 октября 2011

Я хочу реализовать сервер сокетов UDP (используя c под Linux). Я хочу избежать зависания клиента путем разветвления нового процесса, когда сервер получает новое сообщение от клиента. (я не хочу использовать потоки)

Проблема в том, что сервер продолжает ждать (блокировка функции recvfrom), но когда клиент отправляет первое сообщение, сервер продолжает разветвлять МНОГИЕ процессы (похоже, что он получает сообщение больше, чем один раз или как клиент отправляет его много раз, на самом деле я не знаю, где проблема)

Сервер:

// socket file descriptor (socket descriptor)
int socket_fd;
// serverTCP and client addresses
struct sockaddr_in server_addr, client_addr;
socklen_t sin_size;
int bytes_read;
char recv_data[1024];

// create the socket
if ((socket_fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
    perror("UDP Server: ERROR while creating the socket.\n");
    exit(1);
}

// define the socket address associated with the created socket
// set the server address and port number

// set the binding of the serverUDP socket
printf("\nUDP Server: server socket binding...");
if (bind(socket_fd, (struct sockaddr *) &server_addr, sizeof(struct sockaddr)) == -1) {
    perror("UDP Server: ERROR while binding the socket.\n");
    exit(1);
}
printf("\nUDP Server: done binding.");

sin_size = sizeof(struct sockaddr);
// block and wait for connection request
int pid; // process ID for forking new serverUDP process
while (1) {
    printf("\nUDP Server: waiting for connection...");
    bytes_read = recvfrom(socket_fd, recv_data, 1023, 0,
            (struct sockaddr *) &client_addr, &sin_size);

    // a connection has been established
    recv_data[bytes_read] = '\0';
    printf("\nUDP Server: received -> %s", recv_data);
    pid = fork();

    if (pid < 0) {
        perror("UDP Server: ERROR while forking new process.\n");
        exit(1);
    }
    // check if the process ID is zero
    if (pid == 0) {
        // we are now inside the new forked process
        char result[50];
        int len = sprintf(result, "%d", server_parse_command(recv_data));
        len = sendto(socket_fd, result, len, 0,
                (struct sockaddr *) &client_addr, sin_size);
        close(socket_fd);
        exit(0);
    }
}

Клиент:

int socket_fd;
struct sockaddr_in server_addr;
struct hostent *host;
host = gethostbyname("127.0.0.1");

// create the socket
if ((socket_fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
    perror("UDP Client: ERROR while creating the socket.\n");
    exit(1);
}
// define the socket address associated with the created socket
    // set the client address and port number

// send messages to the server socket
int count;
char buffer[128];
while (1) {
    socklen_t sin_size = sizeof(struct sockaddr);
    // read message to send to the server and set count to the length of the message

    count = sendto(socket_fd, buffer, count, 0,
            (struct sockaddr *) &server_addr, sizeof(struct sockaddr));
    if (count < 0) {
        perror("UDP Client: ERROR while writing message to server socket.\n");
        exit(1);
    }
    bzero(buffer, 128);
    count = recvfrom(socket_fd, buffer, 127, 0,
            (struct sockaddr *) &server_addr, &sin_size) ;

    if (count < 0) {
        perror("UDP Client: ERROR while reading response from server socket.\n");
        exit(1);
    }
    buffer[count] = '\0';
    printf("\nUDP Client: received response -> %s", buffer);
    close(socket_fd);
}

Извините за длинный код.

1 Ответ

1 голос
/ 26 января 2015

(Ответ ОП в редакции. См. Вопрос без ответов, но проблема решена в комментариях (или расширена в чате) )

ОП написал:

Я наконец-то решил проблему, я просто поставлю решение, если кто-то сталкивался с этим.

В реализации сервера и внутри цикла while(1). проверьте, получен ли bytes_read> 0 , прежде чем что-либо делать, в противном случае продолжайте цикл, так что это будет примерно так:

while (1) {
    printf("\nUDP Server: waiting for connection...");
    bytes_read = recvfrom(socket_fd, recv_data, 1023, 0,
            (struct sockaddr *) &client_addr, &sin_size);

    if (bytes_read > 0) {
                // a connection has been established
            recv_data[bytes_read] = '\0';
                printf("\nUDP Server: received -> %s", recv_data);
            pid = fork();

            if (pid < 0) {
                perror("UDP Server: ERROR while forking new process.\n");
                exit(1);
            }
            // check if the process ID is zero
            if (pid == 0) {
                // we are now inside the new forked process
                char result[50];
                int len = sprintf(result, "%d", server_parse_command(recv_data));
                len = sendto(socket_fd, result, len, 0,
                (struct sockaddr *) &client_addr, sin_size);
                close(socket_fd);
                exit(0);
            }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...