搭建一个后台服务器--服务端代码(异步,大并发)
#include <stdio.h>#include <time.h>#include <fcntl.h>#include <stdlib.h>#include <errno.h>#include <string.h>#ifndef WIN32#include <unistd.h>#include <sys/epoll.h>#include <sys/types.h>#include <sys/socket.h>#include <arpa/inet.h>#include <netinet/in.h>#else#include <WinSock2.h>#define close( f ) closesocket( f )#endifstruct my_event_s{int fd;char recv[64];char send[64];int rc_pos;int sd_pos;};int main( int argc, char** argv ){int port;int flag;int size;int sock_server;int sock_client;time_t current;time_t last;int num;int e_num;int my_empty_index;int i,j;int event_flag;#define EPOLL_MAX 51200struct epoll_event wait_events[ EPOLL_MAX ];struct my_event_s my_event[ EPOLL_MAX ];struct my_event_s* tobe_myevent;struct epoll_event tobe_event;int epfd;#define RECV_BUF_LEN 256char buffer[ RECV_BUF_LEN ];struct sockaddr_in addr_server;struct sockaddr_in addr_client;if( argc <= 1 ){printf( "please set your port\n" );return 0;}printf( "your port:%s\n", argv[1] );#ifdef WIN32WSADATA wsadata;flag = WSAStartup( 0x101, &wsadata );if( flag ){printf( "your windows socket setup wrong\n" );return 0;}#endifport = atoi(argv[1]);addr_server.sin_family = AF_INET;addr_server.sin_port = htons( port );addr_server.sin_addr.s_addr = htonl( INADDR_ANY );sock_server = socket( AF_INET, SOCK_STREAM, 0 );flag = fcntl( sock_server, F_GETFL, 0 );fcntl( sock_server, F_SETFL, flag | O_NONBLOCK );flag = bind( sock_server, ( struct sockaddr* )&addr_server, sizeof( struct sockaddr ) );if( flag < 0 ){printf( "your bind is not ok\n" );close( sock_server );return 0;}flag = listen( sock_server, 1024 );if( flag < 0 ){printf( "your listen is not ok\n");close( sock_server );return 0;}epfd = epoll_create( EPOLL_MAX );if( epfd <= 0 ){printf( "event module could not be setup\n");close( sock_server );return 0;}tobe_event.events = EPOLLIN;tobe_event.data.fd = sock_server;epoll_ctl( epfd, EPOLL_CTL_ADD, sock_server, &tobe_event );size = sizeof( addr_client );num = 0;last = 0;my_empty_index = 0;while(1){#define WAIT_TIME_OUT 600e_num = epoll_wait( epfd, wait_events, EPOLL_MAX, WAIT_TIME_OUT );if( e_num <= 0 ){continue;}for( i = 0; i < e_num; ++i ){if( sock_server == wait_events[ i ].data.fd ){while(1){sock_client = accept( sock_server, ( struct sockaddr* )&addr_client, ( socklen_t*)&size );if( sock_client < 0 ){if( errno == EAGAIN ){break;}if( errno == EINTR ){continue;}break;}tobe_myevent = my_event + my_empty_index;memset( tobe_myevent, 0, sizeof( struct my_event_s ) );tobe_myevent->fd = sock_client;flag = fcntl( sock_client, F_GETFL, 0 );fcntl( sock_client, F_SETFL, flag | O_NONBLOCK );tobe_event.events = EPOLLIN | EPOLLET;tobe_event.data.u32 = my_empty_index;epoll_ctl( epfd, EPOLL_CTL_ADD, sock_client, &tobe_event );for( j = my_empty_index + 1; j < EPOLL_MAX; ++j ){if( !my_event[ j ].fd ){my_empty_index = j;break;}}if( my_event[j].fd ){for( j = 0; j < EPOLL_MAX; ++j ){if( !my_event[ j ].fd ){my_empty_index = j;break;}}if( my_event[ j ].fd ){printf( "your events has been none else\n");close( sock_client );close( sock_server );return 0;}}++num;current = time( 0 );if( current > last ){printf( "last sec qps:%d\n", num );num = 0;last = current;}memcpy( tobe_myevent->send, ¤t, sizeof(time_t) );flag = recv( sock_client, tobe_myevent->recv, 64, 0 );if( flag < 64 ){if( flag > 0 )tobe_myevent->rc_pos += flag;continue;}if( tobe_myevent->recv[31] || tobe_myevent->recv[63] ){printf( "your recv does follow the protocal\n");tobe_myevent->fd = 0;close( sock_client );continue;}flag = send( sock_client, tobe_myevent->send, sizeof( time_t ), 0 );if( flag < sizeof( time_t ) ){tobe_event.events = EPOLLET | EPOLLOUT;epoll_ctl( epfd, EPOLL_CTL_MOD, sock_client, &tobe_event );if( flag > 0 )tobe_myevent->sd_pos += flag;continue;}tobe_myevent->fd = 0;close( sock_client );}}else{tobe_myevent = my_event + wait_events[ i ].data.u32;sock_client = tobe_myevent->fd;event_flag = wait_events[ i ].events;if( event_flag | EPOLLHUP ){tobe_myevent->fd = 0;close( sock_client );continue;}else if( event_flag | EPOLLERR ){tobe_myevent->fd = 0;close( sock_client );continue;}else if( event_flag | EPOLLOUT ){if( tobe_myevent->rc_pos != 64 ){continue;}if( tobe_myevent->sd_pos >= sizeof( time_t ) ){tobe_myevent->fd = 0;close( sock_client );continue;}flag = send( sock_client, tobe_myevent->send + tobe_myevent->sd_pos, sizeof( time_t ) - tobe_myevent->sd_pos, 0 );if( flag < 0 ){if( errno == EAGAIN ){continue;}else if( errno == EINTR ){continue;}tobe_myevent->fd = 0;close( sock_client );continue;}if( flag >0 ){tobe_myevent->sd_pos += flag;if( tobe_myevent->sd_pos >= sizeof( time_t ) ){tobe_myevent->fd = 0;close( sock_client );continue;}}}if( event_flag | EPOLLIN ){if( tobe_myevent->rc_pos < 64 ){flag = recv( sock_client, tobe_myevent->recv + tobe_myevent->rc_pos, 64 - tobe_myevent->rc_pos, 0 );if( flag <= 0 ){continue;}tobe_myevent->rc_pos += flag;if( tobe_myevent->rc_pos < 64 ){continue;}if( tobe_myevent->recv[31] || tobe_myevent->recv[63] ){printf( "your recv does follow the protocal\n");tobe_myevent->fd = 0;close( sock_client );continue;}flag = send( sock_client, tobe_myevent->send, sizeof( time_t ), 0 );if( flag < sizeof( time_t ) ){if( flag > 0 )tobe_myevent->sd_pos += flag;tobe_event.events = EPOLLET | EPOLLOUT;tobe_event.data.u32 = wait_events[i].data.u32;epoll_ctl( epfd, EPOLL_CTL_MOD, sock_client, &tobe_event );continue;}tobe_myevent->fd = 0;close( sock_client );}}}}}printf( "close server connection\n");close( sock_server );return 0;}