unix 网络编程--select (一)

来源:互联网 发布:mac air pro 编辑:程序博客网 时间:2024/06/03 18:51

下面是一个很不错的select的例子,避免了调用fork而产生的新进程的开销:

下面是server 代码:

#include <stdio.h> #include <stdlib.h>#include <sys/types.h>          /* See NOTES */#include <sys/socket.h>#include <netinet/in.h>#include <string.h>#include <errno.h>#include <unistd.h>#include <arpa/inet.h>#define MAXLINE  1024typedef struct sockaddr_in sockaddr_in ;typedef struct sockaddr sockaddr ;#define MAX_FD_CONN1000int main(int argc ,char ** argv){int sock ,con;int nready ,nfd;sockaddr_in srv,cli ;if((sock=socket(AF_INET ,SOCK_STREAM,0))==-1){perror("socket ");return -1 ;}bzero(&srv,0);srv.sin_family = AF_INET ;srv.sin_port = htons(8070);srv.sin_addr.s_addr = htonl (INADDR_ANY) ;if((bind(sock,(sockaddr*)&srv,sizeof(sockaddr)))< 0){perror("bind");return -1 ;}listen(sock,10);char buf[1024];fd_set rset,allfd ;int conns[ MAX_FD_CONN ] ,i ,nr;socklen_t len ;for(i =0 ;i<MAX_FD_CONN;i++)conns[i] = -1;FD_ZERO(&allfd);FD_SET(sock,&allfd );nfd = sock+1;FD_SET(sock,&allfd);while(1){rset=allfd; //这个是相当的关键一行哦,UNP(1)上说,select 对参数是有修改的,一定要注意保存啊,不然会出现意想不到的问题nready = select(nfd, &rset,NULL,NULL,NULL );if (FD_ISSET(sock,&rset)) {len = sizeof(sockaddr);if ((con = accept(sock, (sockaddr*) &cli, &len)) == -1) {perror("accept");continue;}for(i =0 ;i<MAX_FD_CONN;i++){ /*if maxsize >MAX_FD_CONN, throw and close the connect */if(conns[i ] == -1){conns[i] = con;FD_SET(con,&allfd);break;}}if(MAX_FD_CONN == i)close(con);if(nfd <= con)nfd = con +1;if(--nready <= 0){continue ;}}for(i =0 ;i<MAX_FD_CONN;i++){if(conns[i]== -1)continue ;if(FD_ISSET(conns[i], &rset)){bzero(buf,sizeof(buf));if((nr=read(conns[i],buf,sizeof(buf)))<=0){close(conns[i]);FD_CLR(conns[i],&allfd);continue ;}else{printf("read:%s\n",buf);write(conns[i],buf, nr);}}if(--nready <= 0)break;}}close(sock);return 0;}

在此我也把客户端连接的测试的代码也贴出来,分享一下,也防止以后忘了呵呵呵

#include <stdio.h> #include <stdlib.h>#include <sys/types.h>          /* See NOTES */#include <sys/socket.h>#include <netinet/in.h>#include <string.h>#include <errno.h>#include <unistd.h>#include <arpa/inet.h>#define MAXLINE  1024typedef struct sockaddr_in sockaddr_in ;typedef struct sockaddr sockaddr ;int main(int argc ,char ** argv){int sock ;int sel ,nfd;sockaddr_in srv,cli ;if((sock=socket(AF_INET ,SOCK_STREAM,0))==-1){perror("socket ");return -1 ;}bzero(&srv,0);srv.sin_family = AF_INET ;srv.sin_port = htons(atoi(argv[2]));inet_pton(AF_INET,argv[1],&srv.sin_addr);char buf[1024];fd_set rset ,wset;FD_ZERO(&rset);FD_ZERO(&wset);FD_SET(STDIN_FILENO ,&rset );FD_SET(sock ,&rset );if(connect(sock,(sockaddr*)&srv, sizeof(sockaddr))<0){perror("connect:");return -1 ;}perror("con");nfd = sock+1;int rn ;bzero(buf,sizeof(buf));while((sel = select(nfd, &rset,&wset,NULL,NULL ))){printf("select begin\n");if(FD_ISSET(sock,&rset)){bzero(buf,sizeof(buf));read(sock,buf,sizeof(buf));printf("read:%s\n",buf);}if(FD_ISSET(STDIN_FILENO,&rset)){bzero(buf,sizeof(buf));rn = read(STDIN_FILENO, buf,sizeof(buf));if(rn>0)FD_SET(sock,&wset );}if(FD_ISSET(sock, &wset)){int wn = write(sock,buf,rn );bzero(buf,sizeof(buf));FD_CLR(sock,&wset );}FD_SET(STDIN_FILENO ,&rset );FD_SET(sock ,&rset );}close(sock);return 0;}
下面给出一个性能测试实例
下面使用200个线程,而且是并发执行哦!每个线程写入1000*1000*10B的数据
测试成功
typedef struct sockaddr_in      sockaddr_in;typedef struct sockaddr         sockaddr ;void *thread_fun(void*arg ){            struct sockaddr_in ser,cli ;        int fd ,bs,fdc,i;        socklen_t len;        char buf[1024];        bzero(&ser,sizeof(sockaddr));        ser.sin_port = 8080;        inet_pton(AF_INET,"10.33.28.230",(void*)&ser.sin_addr);        ser.sin_family = AF_INET ;        fd = socket(AF_INET,SOCK_STREAM, 0);         if(fd<0)                perror("socket error\n");        //int nZero=0;        //setsockopt(fd,SOL_SOCKET,SO_SNDBUF,(char *)&nZero,sizeof(nZero));        printf("threadID:%d\n",(int)arg);        sleep(2);        connect(fd,(sockaddr*)&ser,sizeof(sockaddr));        for(i=0;i<1000*1000;i++){                bzero(buf,sizeof(buf));                sprintf(buf,"%10d",(int)arg);                if(write(fd,buf,strlen(buf))<=0)                        perror("write error:");        }   //      printf("%d\n",i);        close(fd);//      sleep(1);        pthread_exit((void*)arg);}const int num_thre = 200;int main(){        int i =0;        int res;       pthread_t send_msg[num_thre];        for(i=0;i<num_thre;i++){                if(pthread_create(send_msg+i,NULL,thread_fun,i)!=0)                        printf("pthread create error\n");        }        for(i=0;i<num_thre;i++){                pthread_join(send_msg[i],(void**)(&res));                printf("%dover\n",res);        }        printf("over \n");        return 0;}


	
				
		
原创粉丝点击