当前位置: 代码迷 >> 综合 >> unix 网络编程--select (一)
  详细解决方案

unix 网络编程--select (一)

热度:53   发布时间:2023-12-09 13:34:56.0

下面是一个很不错的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  1024
typedef struct sockaddr_in sockaddr_in ;
typedef struct sockaddr sockaddr ;
#define MAX_FD_CONN		1000int 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  1024
typedef 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;
}




  相关解决方案