UDP套接字编程 - 在recev上的fork服务器

时间:2011-10-22 10:28:02

标签: sockets udp

我想实现UDP套接字服务器(在Linux下使用c)。我想避免在服务器从客户端收到新消息时通过分叉新进程来挂起客户端。 (我不想使用线程)

问题是服务器一直在等待(阻止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 个答案:

答案 0 :(得分:1)

(OP在编辑中回答。见Question with no answers, but issue solved in the comments (or extended in chat)

OP写道:

  

我终于解决了这个问题,我只是提出解决方案,我有人会面对它。

     

在服务器实现中和while(1)循环内部。 检查收到的bytes_read&gt; 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);
            }
    }
}