linux下高并发服务器实现( 六 )


bzero(&server,sizeof(server));
server.sin_family=AF_INET;
server.sin_port=htons(PORT);
server.sin_addr.s_addr = htonl (INADDR_ANY);
if( bind(listenfd, (struct sockaddr *)&server, sizeof(struct sockaddr)) == -1 ){
/* handle exception */
perror("Bind error.");
exit(1);
}
 
if(listen(listenfd,BACKLOG) == -1){ /* calls listen() */
perror("listen() errorn");
exit(1);
}
sin_size = sizeof(struct sockaddr_in);
 
/*initialize for select */
maxfd = listenfd;
maxi = -1;
for( i = 0; i<FD_SETSIZE; i++ ){
client[i].fd = -1;
}
 
FD_ZERO( &allset );
FD_SET( listenfd, &allset );
while(1){
struct sockaddr_in addr;
rset = allset;
nready = select( maxfd+1, &rset, NULL, NULL, NULL );
printf("select saw rset actions and the readfset num is %d. n",nready );
if( FD_ISSET(listenfd, &rset) ){
/* new client connection */
/* Accept connection */
printf("accept a connection.n");
if(( connectfd = accept(listenfd,(struct sockaddr *)&addr,(socklen_t *)&sin_size))==-1 ){
perror("accept() errorn");
continue;
}
 
/* Put new fd to client */
for( i = 0; i < FD_SETSIZE; i++ ){
if (client[i].fd < 0) {
client[i].fd = connectfd; /* save descriptor */
client[i].addr = addr;
client[i].data[0] = '';
printf("You got a connection from %s. ",inet_ntoa(client[i].addr.sin_addr) );
break;
}
}
 
printf("add new connect fd.n");
if(i == FD_SETSIZE ) printf("too many clientsn");
FD_SET( connectfd, &allset ); /* add new descriptor to set */
if( connectfd > maxfd ) maxfd = connectfd;
if( i > maxi ) maxi = i;
if( --nready <= 0 ) continue; /* no more readable descriptors */
}
 
for( i = 0; i <= maxi; i++ ){
/* check all clients for data */
if( (sockfd = client[i].fd) < 0 ) continue; /* no more connected clients*/
if( FD_ISSET(sockfd, &rset) ){
printf( "recv occured for connect fd[%d].n",i );
if( (n = recv(sockfd, recvbuf, MAXDATASIZE,0) ) == 0 ){
/*connection closed by client */
close(sockfd);
printf("Client( %d ) closed connection.n",client[i].fd );
FD_CLR(sockfd, &allset);
client[i].fd = -1;
}
else{
process_cli( &client[i], recvbuf, n );
}
if (--nready <= 0) break; /* no more readable descriptors */
}
}
 
}
close(listenfd); /* close listenfd */
}
 
void process_cli( CLIENT *client, char* recvbuf, int len )
{
send( client->fd, recvbuf, len, 0 );
}
例子:epoll使用

#include <unistd.h>
#include <sys/types.h> /* basic system data types */
#include <sys/socket.h> /* basic socket definitions */
#include <netinet/in.h> /* sockaddr_in{} and other Internet defns */
#include <arpa/inet.h> /* inet(3) functions */
#include <sys/epoll.h> /* epoll function */
#include <fcntl.h> /* nonblocking */
#include <sys/resource.h> /*setrlimit */
 
#include <stdlib.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
 
#define MAXEPOLLSIZE 10000
#define MAXLINE 10240
 
int handle(int connfd);
 
int setnonblocking( int sockfd )
{
if( fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFD, 0)|O_NONBLOCK) == -1) {
return -1;
}
return 0;
}
 
int main(int argc, char **argv)
{
int servPort = 6888;
int listenq = 1024;
 
int listenfd, connfd, kdpfd, nfds, n, nread, curfds,acceptCount = 0;
struct sockaddr_in servaddr, cliaddr;
socklen_t socklen = sizeof(struct sockaddr_in);
struct epoll_event ev;
struct epoll_event events[MAXEPOLLSIZE];
struct rlimit rt;
char buf[MAXLINE];
 
/*设置每个进程允许打开的最大文件数
rt.rlim_max = rt.rlim_cur = MAXEPOLLSIZE;
if( setrlimit( RLIMIT_NOFILE, &rt ) == -1 ){
perror("setrlimit error");
return -1;
} */
 
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(servPort);
 
listenfd = socket(AF_INET, SOCK_STREAM, 0);
if (listenfd == -1) {
perror("can't create socket file");
return -1;
}
 
int opt = 1;


推荐阅读