Article Title: Linux Network Programming-9. server model. Linux is a technology channel of the IT lab in China. Includes basic categories such as desktop applications, Linux system management, kernel research, embedded systems, and open source.
I have studied software engineering. software Engineering is a required course for every programmer. if you have never studied, we suggest you take a look. in this chapter, we will learn the idea of network programming from the perspective of software engineering. before writing programs, we should plan our software from the perspective of software engineering, so that we can develop software more efficiently. in network programs, many clients usually correspond to one server. in order to process client requests, special requirements are put forward for the server program. let's take a look at the most common server models.
Cyclic server: At the same time, the cyclic server can only respond to requests from one client.
Concurrent Server: the concurrent server can respond to requests from multiple clients at the same time.
9.1 circulating server: UDP Server
The implementation of UDP cyclic server is very simple: the UDP server reads a client request from the socket each time, processes the request, and then returns the result to the client.
The following algorithm can be used for implementation.
Socket (...);
Bind (...);
While (1)
{
Recvfrom (...);
Process (...);
Sendto (...);
}
Because UDP is non-connection-oriented, no client can occupy the server. As long as the processing process is not an endless loop, the server will always be able to meet the requirements of each client.
9.2 cyclic server: TCP Server
The implementation of the TCP cyclic server is not difficult: the TCP Server accepts a client connection, processes it, completes all the requests of the client, and disconnects.
The algorithm is as follows:
Socket (...);
Bind (...);
Listen (...);
While (1)
{
Accept (...);
While (1)
{
Read (...);
Process (...);
Write (...);
}
Close (...);
}
The TCP cyclic server can only process requests from one client at a time. the server can continue the subsequent request only after all the requests of this customer are met. in this way, if a client occupies the server, other clients cannot work. therefore, the TCP server rarely uses the cyclic server model.
9.3 concurrent server: TCP Server
To make up for the defects of the cyclic TCP server, people have come up with a concurrent server model. the idea of a concurrent server is that the request of each client is not directly processed by the server, but is created by the server to process the request.
The algorithm is as follows:
Socket (...);
Bind (...);
Listen (...);
While (1)
{
Accept (...);
If (fork (..) = 0)
{
While (1)
{
Read (...);
Process (...);
Write (...);
}
Close (...);
Exit (...);
}
Close (...);
}
The TCP concurrent server can solve the problem that the TCP cyclic Server Client exclusively occupies the server. however, it also brings a lot of problems. to respond to client requests, the server creates sub-processes to process the requests. creating a sub-process is a resource-consuming operation.
9.4 concurrent server: multiplexing I/O
To solve the system resource consumption caused by the creation of sub-processes, we have come up with a multiplexing I/O model.
Generally, when we read and write data to a file, the process may block reading and writing until certain conditions are met. for example, when we read data from a socket, there may be no data readable in the buffer (the communication peer has not sent the data). At this time, our read call will wait (blocking) until data is readable. if we do not want to block it, one of our options is to use the select system call. as long as we have set the select parameters, when the file can be read and written, select back "notice" We say it can be read and written. set of file descriptors of all readfds files to be read
Writefds: a set of all file descriptors to be written.
File descriptor to be notified to us by other Alibaba TFDs servers
Timeout settings.
Nfds adds 1 to the largest file descriptor we monitor.
When we call select, the process will be blocked until one of the following situations occurs. 1) There are files that can be read. 2) There are files that can be written. 3) the time specified for timeout is reached.
To set file descriptors, we need to use several macros. FD_SET to add fd to fdset.
FD_CLR clears fd from fdset
FD_ZERO clears all file descriptors from fdset.
FD_ISSET determines whether fd is in the fdset
An example of using select
Int use_select (int * readfd, int n)
{
Fd_set my_readfd;
Int maxfd;
Int I;
Maxfd = readfd [0];
For (I = 1; I if (readfd [I]> maxfd) maxfd = readfd [I];
While (1)
{
/* Add all file descriptors */
FD_ZERO (& my_readfd );
For (I = 0; I FD_SET (readfd [I], * my_readfd );
/* Process blocking */
Select (maxfd + 1, & my_readfd, NULL, NULL );
/* Something can be read */
For (I = 0; I if (FD_ISSET (readfd [I], & my_readfd ))
{
/* It turns out that I can read it */
We_read (readfd [I]);
}
}
}
After select is used, our server program becomes.
Initial Statement (socket, bind, listen );
While (1)
{
Sets the listener's read/write file descriptor (FD _*);
Call select;
If the listener socket is ready, a new connection request is established.
{
Establish a connection (accept );
Add it to the listener file descriptor;
}
Otherwise, it indicates a descriptor that has been connected.
{
Read or write operations );
}
}
Multiplexing I/O can solve resource restrictions. the UDP loop model is actually used on TCP. this brings about some problems. if the server processes client requests in sequence, some customers may wait for a long time.
9.5 concurrent server: UDP Server
People apply the concept of concurrency to UDP and get the concurrency UDP server model. the concurrent UDP server model is actually simple. like the concurrent TCP server model, the algorithm used to create a sub-process is the same as the concurrent TCP model.
Unless the server takes a long time to process client requests, this model is rarely used.
9.6 A concurrent TCP server instance
# Include
# Include
# Include
# Include
# Include
# Define MY_PORT 8888
Int main (int argc, char ** argv)
{
Int listen_fd, accept_fd;
Struct sockaddr_in client_addr;
Int n;
If (listen_fd = socket (AF_INET, SOCK_STREAM, 0) <0)
{
Printf ("Socket Error: % s \ n \ a", strerror (errno ));
Exit (1 );
}
Bzero (& client_addr, sizeof (struct sockaddr_in ));
Client_addr.sin_family = AF_INET;
Client_addr.sin_port = htons (MY_PORT );
Client_addr.sin_addr.s_addr = htonl (INADDR_ANY );
N = 1;
/* If the server is terminated, the server can be started for the second time without waiting for a period of time */
Setsockopt (listen_fd, SOL_SOCKET, SO_REUSEADDR, & n, sizeof (int ));
If (bind (listen_fd, (struct sockaddr *) & client_addr, sizeof (client_addr) <0)
{
Printf ("Bind Error: % s \ n \ a", strerror (errno ));
Exit (1 );
}
Listen (listen_fd, 5 );
While (1)
{
Accept_fd = accept (listen_fd, NULL, NULL );
If (accept_fd <0) & (errno = EINTR ))
Continue;
Else if (accept_fd <0)
{
Printf ("Accept Error: % s \ n \ a", strerror (errno ));
Continue;
}
If (n = fork () = 0)
{
/* The sub-process processes the client connection */
Char buffer [1024];
Close (listen_fd );
N = read (accept_fd, buffer, 1024 );
Write (accept_fd, buffer, n );
Close (accept_fd); <
The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion;
products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the
content of the page makes you feel confusing, please write us an email, we will handle the problem
within 5 days after receiving your email.
If you find any instances of plagiarism from the community, please send an email to:
info-contact@alibabacloud.com
and provide relevant evidence. A staff member will contact you within 5 working days.