0
我想實現一個UDP套接字服務器(在Linux下使用c)。當服務器收到來自客戶端的新消息時,我想避免掛起客戶端。 (我不想要使用線程)UDP套接字編程 - 在recev上的fork服務器
的問題是,服務器繼續等待(在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);
}
對不起,長代碼。
每次接收時間UDP數據包似乎是極端矯枉過正派生一個新的進程..如果你的服務器每秒接收到不平凡的數據包數量,那將是非常低效的。解決懸掛客戶問題既不必要也不足以解決問題。如果您的客戶因爲沒有及時收到回覆數據包而被掛起,那麼您應該在客戶端解決該問題(例如,通過使用select()或poll()來超時,而不僅僅是阻止接收()調用) –