Lesson 26 - Concurrent Server Network Design
26.1 Description of the problem
In the content of our 24th class operation. There is a condition server and a client. But in life, we encounter a situation more clients. Let's do some simulation on the linux operating system, in a terminal run ./tcp_server, run ./tcp_client program were the other two terminals. We will find the first client program will not run for another response after the response until the end of the first run, and then will run the second. This situation is also called cycle server. This server processing efficiency is very low.
26.2 Solution
To solve the above problem, we introduce a concurrent server, concurrency is meant to simultaneously handle. The method can be used in many (multi-process, multi-threaded, etc.), we have adopted today a multi-method process.
Programming concurrency server. We look at the past we have compiled a run-step procedure: (1) create the socket (2) bind a socket (3) loop: connection is established, data processing (4) end. The problem arises in the third step, when we perform data processing, if not processed data will have to wait before it to establish a new connection. To solve this problem, we can create a child process, so that the child process to deal with data, the parent process can always be in the process of establishing the connection. Each establishes a connection, give it to a child process. This improves efficiency.
tcp_server_fork.c
#include<sys/socket.h>
#include<stdio.h>
#include <string.h> // string header
Headers #include <netinet / in.h> // address
#define portnum 3333
int main ()
{
int sockfd;
int new_fd;
char buffer [128]; // definition storing data bytes
int nbyte; // length of the received string
int sin_size;
struct sockaddr_in server_addr;
struct sockaddr_in client_addr;
int pid;
1 // Create a socket
if ((sockfd = socket (AF_INET, SOCK_STREAM, 0)) == -1)
{
printf("creat socket error!\n");
exit(1);
}
//2.1 set the address to bind
bzero(&server_addr, sizeof(struct sockaddr_in));//清零
server_addr.sin_family = AF_INET; // network protocol
server_addr.sin_port = htons (portnum); // port, more than two bytes will convert
server_addr.sin_addr.s_addr = htonl (INADDR_ANY); // indicates any address, will convert more than two bytes
//2.2 bind address
bind (sockfd, (struct sockaddr *) (& server_addr), sizeof (struct sockaddr)); // pointer indicates cast
// 3. Listen Port
listen(sockfd, 5);
while(1)
{
// 4. Waiting for connection
sin_size = sizeof(struct sockaddr);
new_fd = accept(sockfd, (struct sockaddr *)(&client_addr), &sin_size);
printf ( "server get connection from% s \ n", inet_ntoa (client_addr.sin_addr)); // get ip address of the client, and converts the address to the address of the string integer
// create a child process, handled by the child process data
if (pid = fork () == 0) // create a child process if pid is equal to 0 child process, the parent process is not equal to 0
{
5 // received data
nbyte = recv(new_fd,buffer,128,0);
buffer [nbyte] = '\ 0'; // string terminator
printf("server received: %s \n",buffer);
close(new_fd);
close(sockfd);
exit(0);
}
else if(pid<0)
printf("fork error!\n");
// 6. End connections
close(new_fd);
}
close(sockfd);
return 0;
}
tcp_client.c also program 24 lessons.
The result: We can be individually enabled tcp_server_fork, tcp_client, tcp_client in three ports. We will see tcp_server_fork program can simultaneously handle the program to two clients.