select机制
来源:互联网 发布:淘宝上开网店步骤 编辑:程序博客网 时间:2024/05/16 14:51
server
/************************************************************************* > File Name: server.cpp > Author: > Mail: > Created Time: 2017年06月13日 星期二 20时12分15秒 ************************************************************************/#include<iostream>#include<sys/types.h>#include<sys/socket.h>#include<netinet/in.h>#include<arpa/inet.h>#include<unistd.h>#include<stdio.h>#include<stdlib.h>#include<strings.h>#include<sys/wait.h>#include<string.h>#include<errno.h>#define DEFAULT_PORT 6666using namespace std;int main(int argc,char **argv){ int serverfd,acceptfd; struct sockaddr_in my_addr;//服务器地址 struct sockaddr_in their_addr;//客户端的地址 unsigned int sin_size; unsigned int myport=6666; unsigned int lisnum=10;//一次监听的数目 if((serverfd=socket(AF_INET,SOCK_STREAM,0))==-1){ perror("socket error!\n"); return -1; } printf("socket ok\n"); my_addr.sin_family=AF_INET;//指明IPV4 my_addr.sin_port=htons(DEFAULT_PORT); my_addr.sin_addr.s_addr=INADDR_ANY;//指明服务器地址为任意地址,一般默认网卡地址 bzero(&(my_addr.sin_zero),0);//指明某个变量的前多少个字节为0,这个很奇怪? //解决套接字端 //口号不能立即释放问题,是由于TCP套接字的TIME_WAIT状态引起的int val=1;int ret1=setsockopt(serverfd,SOL_SOCKET,SO_REUSEADDR,(void*)&val,sizeof(int)); if(ret1==-1){ perror("setsockopt error\n"); exit(1); } if(bind(serverfd,(struct sockaddr*)&my_addr,sizeof(struct sockaddr))==-1){ perror("bind error\n"); return -2; } printf("bind ok\n"); if(listen(serverfd,lisnum)==-1){ perror("listen"); return -3; } printf("listen ok\n"); fd_set client_fdset;//监听的文件描述符集合 int maxsock;//监听的文件描述符最大值,其实就是最大文件号 struct timeval tv;//超时返回时间 int client_sockfd[5];//存放活动的sockfd bzero((void *)client_sockfd,sizeof(client_sockfd)); int conn_amount=0;//用来记录文件描述符数量 maxsock=serverfd; char buffer[1024]; int ret=0; while(1) { //初始化文件描述符集合 FD_ZERO(&client_fdset); FD_SET(serverfd,&client_fdset);//把服务器描述符加入描述符集合 tv.tv_sec=30; tv.tv_usec=0;//设置超时时间 for(int i=0;i<5;i++) { if(client_sockfd[i]!=0) FD_SET(client_sockfd[i],&client_fdset);//把活跃的句柄加入到文件描述中 } printf("put sockfd in fdset \n"); ret=select(maxsock+1,&client_fdset,NULL,NULL,&tv); if(ret<0){ perror("select error \n"); break; } else if(ret==0) { printf("time out\n"); continue; } else { int clientsnum=conn_amount; for(int i=0;i<clientsnum;i++)//轮询各个文件描述符 { if(FD_ISSET(client_sockfd[i],&client_fdset))// { printf("start recv from client[%d]:\n",i); ret=recv(client_sockfd[i],buffer,1024,0); if(ret<=0){ printf("client[%d] close\n",i);//这里需要修改,关闭连接时,对应的conn_amount也应该减少,一会测试一下 close(client_sockfd[i]); FD_CLR(client_sockfd[i],&client_fdset); client_sockfd[i]=0; conn_amount--; } else printf("recv from client[%d]:%s\n",i,buffer); } } } if(FD_ISSET(serverfd,&client_fdset)){//有新的连接,接收连接 struct sockaddr_in client_addr; size_t size=sizeof(struct sockaddr_in); int sock_client=accept(serverfd,(struct sockaddr*)(&client_addr),(unsigned int *)(&size));//返回客户端的fd if(sock_client<0){ perror("accept error\n"); continue; } if(conn_amount<5) { client_sockfd[conn_amount++]=sock_client; bzero(buffer,1024); strcpy(buffer,"This is server! Welcome!\n"); send(sock_client,buffer,1024,0); printf("new connection client[%d] %s:%d\n",conn_amount,inet_ntoa(client_addr.sin_addr),ntohs(client_addr.sin_port)); bzero(buffer,sizeof(buffer)); ret=recv(sock_client,buffer,1024,0); if(ret<0){ perror("recv error!\n"); close(serverfd); return -1; } printf("recv: %s\n",buffer); if(sock_client>maxsock) maxsock=sock_client; } else { printf("max connections!!quit!\n"); break; } } } for(int i=0;i<5;i++) { if(client_sockfd[i]!=0) close(client_sockfd[i]); } close(serverfd); return 0;}
client
/************************************************************************* > File Name: client.cpp > Author: > Mail: > Created Time: 2017年06月13日 星期二 21时24分46秒 ************************************************************************/#include<iostream>#include<sys/types.h>#include<sys/socket.h>#include<netinet/in.h>#include<arpa/inet.h>#include<unistd.h>#include<stdio.h>#include<stdlib.h>#include<strings.h>#include<sys/wait.h>#include<string.h>#include<errno.h>#define DEFAULT_PORT 6666using namespace std;int main(int argc,char **argv){ int connfd=0; int cLen=0; struct sockaddr_in client; if(argc<2){ printf("Usage: client [server IP address]\n"); return -1; } client.sin_family=AF_INET; client.sin_port=htons(DEFAULT_PORT); client.sin_addr.s_addr=inet_addr(argv[1]); connfd=socket(AF_INET,SOCK_STREAM,0); if(connfd<0) { perror("socket error\n"); return -1; } if(connect(connfd,(struct sockaddr*)&client,sizeof(client))<0) { perror("connect"); return -1; } char buffer[1024]; bzero(buffer,sizeof(buffer)); recv(connfd,buffer,1024,0); printf("recv: %s\n",buffer); bzero(buffer,sizeof(buffer)); strcpy(buffer,"This is client\n "); send(connfd,buffer,1024,0); while(1) { bzero(buffer,sizeof(buffer)); //scanf("%s",buffer); cin.getline(buffer,sizeof(buffer)); int p=strlen(buffer); printf("buffer is %s\n Len is %d \n",buffer,p); buffer[p]='\0'; send(connfd,buffer,1024,0); printf("i have send buffer\n"); } close(connfd); return 0;}
makefile
all:server clientserver:server.o g++ -g -o server server.oclient:client.o g++ -g -o client client.oserver.o: server.cpp g++ -g -c server.cppclient.o: client.cpp g++ -g -c client.cppclear:all rm all
解决bind错误 bind: Address already in use
http://www.cnblogs.com/Bro-Young/p/5762737.html
(优秀博客,推荐阅读)
阅读全文
0 0
- select()机制
- select机制
- select机制
- select机制
- Select机制--
- select机制
- select机制
- poll select 机制
- linux select 多路复用机制
- linux select 多路复用机制
- Linux select机制
- linux select 多路复用机制
- linux select机制:
- linux select 多路复用机制
- select机制中FD_SET
- poll和select机制
- 浅谈select多路复用机制
- linux select 多路复用机制
- MVC
- AndroidManifest.xml的xml语法层次
- 内容提供者ContentProvider和内容解析者ContentResolver
- [Android]IsoParser讲解
- linux
- select机制
- 彻底删除Windows 7下残留打印机驱动
- 基于Jenkins-2.46.3进行持续集成
- Linux基础记录
- video_device ops in user_space
- Android 中关于 【Cursor】 类的介绍
- 9.高级控件(三)之 RecyclerView
- linux下jdk&tomcat&mysql
- linux:linux常用命令