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


setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
 
if( setnonblocking(listenfd) < 0 ){
perror("setnonblock error");
}
 
if( bind(listenfd, (struct sockaddr *) &servaddr, sizeof(struct sockaddr)) == -1 ){
perror("bind error");
return -1;
}
if( listen(listenfd, listenq) == -1 ){
perror("listen error");
return -1;
}
 
/*创建epoll句柄,把监听 socket 加入到 epoll 集合里 */
kdpfd = epoll_create( MAXEPOLLSIZE );
ev.events = EPOLLIN | EPOLLET;
ev.data.fd = listenfd;
if( epoll_ctl( kdpfd, EPOLL_CTL_ADD, listenfd, &ev ) < 0){
fprintf(stderr, "epoll set insertion error: fd=%dn", listenfd );
return -1;
}
curfds = 1;
 
printf( "epollserver startup, port %d, max connection is %d, backlog is %dn", servPort, MAXEPOLLSIZE, listenq );
 
for (;;) {
/* 等待有事件发生 */
nfds = epoll_wait( kdpfd, events, curfds, -1 );
if (nfds == -1){
perror("epoll_wait");
continue;
}
 
printf( "events hAppen %dn", nfds );
 
/* 处理所有事件 */
for( n = 0; n < nfds; ++n ){
if( events[n].data.fd == listenfd ){
connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &socklen );
if (connfd < 0){
perror("accept error");
continue;
}
 
sprintf(buf, "accept form %s:%dn", inet_ntoa(cliaddr.sin_addr), cliaddr.sin_port);
printf("%d:%s", ++acceptCount, buf);
 
if( curfds >= MAXEPOLLSIZE ){
fprintf(stderr, "too many connection, more than %dn", MAXEPOLLSIZE);
close(connfd);
continue;
}
if( setnonblocking(connfd) < 0 ){
perror("setnonblocking error");
}
ev.events = EPOLLIN | EPOLLET;
ev.data.fd = connfd;
if( epoll_ctl(kdpfd, EPOLL_CTL_ADD, connfd, &ev ) < 0 ){
fprintf(stderr, "add socket '%d' to epoll failed: %sn", connfd, strerror(errno));
return -1;
}
curfds++;
continue;
}
 
// 处理客户端请求
if( handle( events[n].data.fd ) < 0 ){
epoll_ctl(kdpfd, EPOLL_CTL_DEL, events[n].data.fd, &ev );
curfds--;
}
}
}
 
close( listenfd );
return 0;
}
 
int handle( int connfd ) {
int nread;
char buf[MAXLINE];
nread = read(connfd, buf, MAXLINE); //读取客户端socket流
 
if( nread == 0 ){
printf("client close the connectionn");
close(connfd);
return -1;
}
if( nread < 0 ){
perror("read error");
close(connfd);
return -1;
}
write( connfd, buf, nread ); //响应客户端
return 0;
}




推荐阅读