code_tin

从头编写高性能服务程序4-单进程非阻塞select
前面都是阻塞的 当我们在accept或者recv的时候 文件描述符如果没有就绪 整个进程就会被挂起 浪费啊...如...
扫描右侧二维码阅读全文
29
2010/01

从头编写高性能服务程序4-单进程非阻塞select

前面都是阻塞的
当我们在accept或者recv的时候
文件描述符如果没有就绪
整个进程就会被挂起
浪费啊...如果只有就绪的时候才去处理,然后调用之后立刻返回
我们就可以继续做下面的工作了
所以我们引入非阻塞概念
记住,试用setsockopt是无法设置socket接口非阻塞的
只能用fd专用的fcntl去设置fd的非阻塞性质
需要include头文件fcntl.h

还有一点,select所监听的fd_set
在每次select之后就会被清掉
所以一开始我发现每次accept一个数据之后就再也获取不到数据了
然后才发现这点,而这个在我找的资料里面都没提到
所以要把FD_SET放在每次循环里面
我想这也是select性能比较低的原因之一

#include #include #include #include #include #include int main(){ int listen_fd,accept_fd,flag; struct sockaddr_in my_addr,remote_addr; if ( (listen_fd = socket( AF_INET,SOCK_STREAM,0 )) == -1 ){ perror("create socket error"); exit(1); } if ( setsockopt(listen_fd,SOL_SOCKET,SO_REUSEADDR,(char *)&flag,sizeof(flag)) == -1 ){ perror("setsockopt error"); } int flags = fcntl(listen_fd, F_GETFL, 0); fcntl(listen_fd, F_SETFL, flags|O_NONBLOCK); my_addr.sin_family = AF_INET; my_addr.sin_port = htons(3389); my_addr.sin_addr.s_addr = INADDR_ANY; bzero(&(my_addr.sin_zero),8); if ( bind( listen_fd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr_in)) == -1 ) { perror("bind error"); exit(1); } if ( listen( listen_fd,1 ) == -1 ){ perror("listen error"); exit(1); } fd_set fd_sets; int max_fd = listen_fd ; int events=0; int accept_fds[1024]; int i = 0; for(;;){ FD_ZERO( &fd_sets ); FD_SET(listen_fd,&fd_sets); int k=0; for(k=0; k<=i; k++){ FD_SET(accept_fds[k],&fd_sets); } events = select( max_fd + 1, &fd_sets, NULL, NULL, NULL ); if( events ){ printf("events:%d\n",events); if( FD_ISSET(listen_fd,&fd_sets) ){ printf("listen event :1\n"); int addr_len = sizeof( struct sockaddr_in ); accept_fd = accept( listen_fd, (struct sockaddr *)&remote_addr,&addr_len ); int flags = fcntl(accept_fd, F_GETFL, 0); fcntl(accept_fd, F_SETFL, flags|O_NONBLOCK); accept_fds[i] = accept_fd; i++; max_fd = accept_fd ; printf("new accept fd:%d\n",accept_fd); } int j=0; for( j=0; j<=i; j++ ){ if( FD_ISSET(accept_fds[j],&fd_sets) ){ printf("accept event :%d\n",j); char in_buf[1024]; memset(in_buf, 0, 1024); recv( accept_fds[j] ,&in_buf ,1024 ,0 ); printf( "accept:%s\n", in_buf ); } } } } return 0; }

Last modification:November 26th, 2018 at 04:16 pm
If you think my article is useful to you, please feel free to appreciate

Leave a Comment