1. When a client logs on to the server and establishes a persistent connection, the server usually checks whether the client is still connected. If the connection is disconnected, the server no longer provides services to the client,
This server ping mechanism is usually called heartbeat. If the ping information is not received within a certain period of time, the client is disconnected. For example, when the ping information is processed in a high-concurrency connection,
Ping request received by the server,
Note: it can be seen that three clients continuously send the ping heartbeat information to the server. The URI is 5, indicating the ping request, and the URI is 3 indicating the logon. Of course, these are all set by humans,
The above briefly describes the topic of this text. Next we will explain how to implement it on the server side.
Ii. Server initialization:
1. Create an epoll file descriptor to listen for read/write events, as shown below:
Highconcurrentserver: highconcurrentserver (){
If (epfd = epoll_create (maxevents) =-1 ){
Exit (-1 );
}
If (connfd = epoll_create (maxevents) =-1 ){
Exit (-1 );
}
}
2. the IP address, port binding, and socket creation are as follows:
Void highconcurrentserver: initserveraddr (){
STD: String localaddr = "your server IP Address ";
Serveraddr. sin_family = af_inet;
Serveraddr. sin_addr.s_addr =: inet_addr (localaddr. c_str ());
Serveraddr. sin_port = htons (serv_port );
}
Void highconcurrentserver: createsocket (){
Listenfd = socket (af_inet, sock_stream, 0 );
Setnonblocking (listenfd); // set non-blocking. The implementation is simple. Skip this section.
EVT. Data. FD = listenfd;
EVT. Events = epollin | epollet;
Epoll_ctl (connfd, epoll_ctl_add, listenfd, & EVT );
BIND (listenfd, (sockaddr *) & serveraddr, sizeof (serveraddr ));
Listen (listenfd, max_connector );
}
3. Listen to the client connection as follows:
Void highconcurrentserver: connecthandle (){
Int n =-1;
N = epoll_wait (connfd, events, maxevents, 0 );
Int sockfd = 0;
Socklen_t clilen;
For (INT I = 0; I <n; ++ I ){
Printf ("[highconcurrentserver: connecthandle] epoll_wait return result is % d \ n", N );
If (events [I]. Data. FD = listenfd ){
Sockfd = accept (listenfd, (sockaddr *) & clientaddr, & clilen );
Setnonblocking (sockfd );
Char * STR = inet_ntoa (clientaddr. sin_addr );
Printf ("[highconcurrentserver: connecthandle] clientaddr: % s, sockfd: % d, addrlength: % d \ n", STR, sockfd, clilen ); // print the IP address of the output Client
Clientsession * client = new clientsession (sockfd); // creates a clientsession object for each client connection. This object can send and receive data.
Evset. insert (POCO: uint64) (client-> epevent. Data. PTR ));
Epadd (client); // indicates that the sockfd related to this object is listened to with epfd after the connection is successful.
}
}
}
4. send and receive client-related data as follows:
Void highconcurrentserver: readhandle (){
Int n =-1;
N = epoll_wait (epfd, events, maxevents, 0 );
Int sockfd = 0;
Socklen_t clilen;
For (INT I = 0; I <n; ++ I ){
// Check whether the pointer of the event object is null. Skip it here.
Clientsession * client = (clientsession *) (epollevent *) (events [I]. Data. PTR)-> conn;
If (events [I]. Events & (epollerr | epollhup )){
Printf ("[highconcurrentserver: readhandle] epoll Recv err: socket close \ n ");
Client-> close ();
Continue;
}
If (events [I]. Events & epollin ){
# Ifdef open_log
Printf ("[highconcurrentserver: readhandle] epollin event happen \ n ");
# Endif
Client-> recvdata ();
}
/*
If (events [I]. Events & epollout ){
Printf ("[highconcurrentserver: readhandle] epollout event happen \ n ");
Client-> writable = true;
} Else {
Client-> writable = false;
}
*/
}
}
Void highconcurrentserver: writehandle (){
Int n =-1;
N = epoll_wait (epfd, events, maxevents, 0 );
Int sockfd = 0;
Socklen_t clilen;
For (INT I = 0; I <n; ++ I ){
// Check whether the event object is null. skip this step.
Clientsession * client = (clientsession *) (epollevent *) (events [I]. Data. PTR)-> conn;
If (events [I]. Events & (epollerr | epollhup )){
Printf ("[highconcurrentserver: writehandle] epoll Recv err: socket close \ n ");
Client-> close ();
Continue;
}
If (events [I]. Events & epollout ){
# Ifdef open_log
Printf ("[highconcurrentserver: writedhandle] epollout event happen \ n ");
# Endif
}
}
}
5. Service implementation:
Void highconcurrentserver: Service (){
Connecthandle ();
Readhandle ();
Writehandle ();
}
~ To be continued
Reprinted please indicate the source: zhujian blog, http://blog.csdn.net/linyanwen99/article/details/8315779