unix 網路編程--select (一)

來源:互聯網
上載者:User

下面是一個很不錯的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;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.