Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sockets UDP套接字编程-recev上的fork服务器_Sockets_Udp - Fatal编程技术网

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

Sockets UDP套接字编程-recev上的fork服务器,sockets,udp,Sockets,Udp,我想实现一个UDP套接字服务器(在Linux下使用c)。我希望在服务器收到来自客户端的新消息时,通过分叉一个新进程来避免挂起客户端。(我不想使用线程) 问题是服务器一直在等待(recvfrom函数被阻塞),但是当客户端发送第一条消息时,服务器不断地进行许多处理(看起来它不止一次地接收消息,或者客户端多次发送消息,我真的不知道问题出在哪里) 服务器: // socket file descriptor (socket descriptor) int socket_fd; // serverTCP

我想实现一个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);
}
//套接字文件描述符(套接字描述符)
int-socket_-fd;
//serverTCP和客户端地址
服务器地址、客户端地址中的结构sockaddr\u;
袜子的大小;
读取整数字节;
字符记录数据[1024];
//创建套接字
if((socket\u fd=socket(AF\u INET,SOCK\u DGRAM,0))=-1){
perror(“UDP服务器:创建套接字时出错。\n”);
出口(1);
}
//定义与创建的套接字关联的套接字地址
//设置服务器地址和端口号
//设置serverUDP套接字的绑定
printf(“\nUDP服务器:服务器套接字绑定…”);
if(bind(socket_fd,(struct sockaddr*)和server_addr,sizeof(struct sockaddr))=-1){
perror(“UDP服务器:绑定套接字时出错。\n”);
出口(1);
}
printf(“\nUDP服务器:完成绑定。”);
sin_size=sizeof(结构sockaddr);
//阻塞并等待连接请求
int-pid;//分叉新serverUDP进程的进程ID
而(1){
printf(“\nUDP服务器:正在等待连接…”);
字节读取=recvfrom(套接字fd,recv_数据,1023,0,
(结构sockaddr*)和客户机地址及大小);
//已建立连接
记录数据[字节读取]='\0';
printf(“\nUDP服务器:收到->%s”,接收数据);
pid=fork();
if(pid<0){
perror(“UDP服务器:分叉新进程时出错。\n”);
出口(1);
}
//检查进程ID是否为零
如果(pid==0){
//我们现在进入了新的分叉过程
字符结果[50];
int len=sprintf(结果,“%d”,服务器解析命令(recv_数据));
len=sendto(套接字,结果,len,0,
(结构sockaddr*)和客户端地址、大小);
关闭(插座f);
出口(0);
}
}
客户端:

// 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);
}
int-socket\u-fd;
服务器地址中的结构sockaddr\u;
结构主机*主机;
主机=gethostbyname(“127.0.0.1”);
//创建套接字
if((socket\u fd=socket(AF\u INET,SOCK\u DGRAM,0))=-1){
perror(“UDP客户端:创建套接字时出错。\n”);
出口(1);
}
//定义与创建的套接字关联的套接字地址
//设置客户端地址和端口号
//将消息发送到服务器套接字
整数计数;
字符缓冲区[128];
而(1){
socklen\u t sin\u size=sizeof(结构sockaddr);
//读取要发送到服务器的邮件,并将计数设置为邮件的长度
计数=发送到(套接字、缓冲区、计数、0、,
(struct sockaddr*)和服务器地址,sizeof(struct sockaddr));
如果(计数<0){
perror(“UDP客户端:将消息写入服务器套接字时出错。\n”);
出口(1);
}
bzero(缓冲器,128);
计数=recvfrom(套接字、缓冲区、127、0、,
(结构sockaddr*)和服务器地址以及大小);
如果(计数<0){
perror(“UDP客户端:从服务器套接字读取响应时出错。\n”);
出口(1);
}
缓冲区[计数]='\0';
printf(“\nUDP客户端:收到响应->%s”,缓冲区);
关闭(插座f);
}
抱歉,代码太长。

(由编辑中的OP回答。请参阅)

OP写道:

我终于解决了这个问题,我会把解决方案放在我遇到的情况下

在服务器实现中以及
while(1)
循环中在执行任何操作之前,检查接收到的字节是否读取>0,否则继续循环,因此将是这样的:

while(1){
printf(“\nUDP服务器:正在等待连接…”);
字节读取=recvfrom(套接字fd,recv_数据,1023,0,
(结构sockaddr*)和客户机地址及大小);
如果(字节读取>0){
//已建立连接
记录数据[字节读取]='\0';
printf(“\nUDP服务器:收到->%s”,接收数据);
pid=fork();
if(pid<0){
perror(“UDP服务器:分叉新进程时出错。\n”);
出口(1);
}
//检查进程ID是否为零
如果(pid==0){
//我们现在进入了新的分叉过程
字符结果[50];
int len=sprintf(结果,“%d”,服务器解析命令(recv_数据));
len=sendto(套接字,结果,len,0,
(结构sockaddr*)和客户端地址、大小);
关闭(插座f);
出口(0);
}
}
}

每次收到UDP数据包时,都要分叉一个新进程,这似乎是一种极端的过激行为。。。如果您的服务器每秒接收的数据包数量非常多,那么效率将非常低。这对于解决挂起的客户端问题既不必要也不充分。如果您的客户端由于没有及时收到回复数据包而挂起,那么您应该在客户端解决该问题(例如,使用select()或poll()进行超时,而不仅仅是阻塞recv()调用)