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;}
- unix 网络编程--select (一)
- UNIX网络编程(一)
- select和poll函数《UNIX网络编程卷一》笔记
- unix 网络编程 select 讲解
- UNIX网络编程之IO复用(一):select系统调用
- unix网络编程(笔记一)
- UNIX网络编程--简介(一)
- unix网络编程笔记(一)
- unix网络编程笔记(一)
- Unix网络编程读书笔记(一)
- Unix网络编程之广播(一)
- UNIX网络编程笔记(一)
- unix高级编程-多路IO select
- UNIX网络编程:select,epoll,poll比较
- Unix网络编程select、poll、epoll比较
- 《unix网络编程》(13)select、shutdown函数
- UNIX网络编程3 使用select()
- UNIX网络编程:select,epoll,poll比较
- 缓存
- HDU 4431 Mahjong (模拟) #by Plato
- POJ1159 Palindrome
- 单片机C语言下LCD多级菜单的一种实现方法
- Wget下载终极用法和15个详细的例子
- unix 网络编程--select (一)
- MFC进修笔记2——MFC和Win32
- NOIP2012纪念
- 数据结构---->数组
- 由前序和中序确定一棵二叉树
- 简单解析xml属性值
- 黑马程序员------装饰设计模式
- Java上路06-面向对象
- POJ1458 Common Subsequence