Linux Network Programming-Server Model (zz)
Address: http://study.pay500.com/1/s12212.htm
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 cyclic Server:
UDP Server
The implementation of UDP loop server is very simple:
Each time the UDP server reads a client request from the socket, processes the request, and 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 client of the TCP cyclic server exclusively occupies the server.
To respond to client requests, the server needs to create sub-processes for processing. Creating Sub-processes is a resource-consuming operation.
9.4 concurrent servers:
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.
First introduce a function select
Int select (INT NFDs,
Fd_set * readfds, fd_set * writefds,
Fd_set * doesn t FDS,
Struct timeval * timeout
)
Void fd_set (int fd, fd_set * fdset)
Void fd_clr (int fd, fd_set * fdset)
Void fd_zero (fd_set * fdset)
Int fd_isset (int fd, fd_set * fdset)
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 recipient has not sent the data ),
At this time, our read call will wait (blocking) until there is data readable. If we do not want to block,
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
Set of all file descriptors to be written in writefds
File descriptor to be notified to us by other Alibaba TFDs servers
Timeout 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) files can be read.
2) files can be written.
3) the time specified for the timeout period is up.
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 <n; I ++)
{
If (readfd [I]> maxfd) maxfd = readfd [I];
}
While (1)
{
/* Add all file descriptors */
Fd_zero (& my_readfd );
For (I = 0; I <n; I ++)
Fd_set (readfd [I], * my_readfd );
/* Process blocking */
Select (maxfd + 1, & my_readfd, null, null );
/* Something can be read */
For (I = 0; I <n; 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.
Concurrent Server: UDP Server
People apply the concept of concurrency to UDP and get the concurrency UDP server model.
The concurrency UDP server model is actually simple. The same as the concurrency TCP server model is
The algorithm to create a sub-process to process is the same as the concurrency TCP model.
Unless the server takes a long time to process client requests, this model is rarely used.