select监听多个socket的例子
来源:互联网 发布:网络女直播 编辑:程序博客网 时间:2024/05/16 06:22
先贴上代码,回头再仔细编辑。
server.cpp:
#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <unistd.h>#include <stdlib.h>#include <assert.h>#include <stdio.h>#include <string.h>#include <errno.h>#include <fcntl.h>#include <vector>using namespace std;int main(int argc,char* argv[]){ printf("server start up\n"); if(argc <= 3) { printf("usage:%s ip port backlog\n",basename(argv[0])); return 1; } //IP地址 const char* ip = argv[1]; //端口号 int port = atoi(argv[2]); //内核监听队列的最大长度(完全连接的socket) int backlog = atoi(argv[3]); //创建socket(TIP/IP协议族,流式socket) int server_sockfd = socket(PF_INET,SOCK_STREAM,0); //最大连接数,初始化为server_sockfd int max_fd = server_sockfd; // vector<int> connFds; connFds.reserve(backlog); //TCP/IP协议族的socket地址结构体 struct sockaddr_in server_addr; bzero(&server_addr,sizeof(server_addr)); server_addr.sin_family = AF_INET;//TCP/IPv4的地址族 inet_pton(AF_INET,ip,&server_addr.sin_addr);//将IP地址字符串转换为二进制的整数并赋给addr.sin_server_addr server_addr.sin_port = htons(port);//端口,host to net,将主机字节序(小端)转换为网络字节序(大端) //将文件描述符sock和socket地址关联,仅服务端需要,客户端自动绑定地址 //注意需要强制转换为 struct sockaddr* int ret = bind(server_sockfd,(struct sockaddr*)&server_addr,sizeof(server_addr)); assert(ret != -1); //监听 ret = listen(server_sockfd,backlog); assert(ret != -1); //客户端地址信息 struct sockaddr_in client_addr; socklen_t client_addrlength = sizeof(client_addr); char buf[1024]; memset(buf,0,sizeof(buf)); //文件描述符集合 fd_set read_fds; fd_set exception_fds; FD_ZERO(&read_fds); FD_ZERO(&exception_fds); //超时 struct timeval timeout; timeout.tv_sec = 30; //妙 timeout.tv_usec = 0 ; //微秒 while(1) { FD_SET(server_sockfd,&read_fds); for(int i =0;i<connFds.size();++i) { FD_SET(connFds[i],&read_fds); FD_SET(connFds[i],&exception_fds); } int ret = select(max_fd+1,&read_fds,NULL,&exception_fds,NULL); if( ret == -1) { perror("select"); break; } else if( ret == 0) { perror("timeout"); break; } for(vector<int>::iterator it = connFds.begin();it != connFds.end();) { memset(buf,0,sizeof(buf)); if( FD_ISSET(*it,&read_fds) ) { int ret = recv(*it,buf,sizeof(buf)-1,0); if(ret <= 0) { perror("recv"); close(*it); FD_CLR(*it,&read_fds); it = connFds.erase(it); printf("A client disconnectd\n"); continue; } buf[ret] = '\0'; printf("%s",buf); } else if(FD_ISSET(*it,&exception_fds)) { int ret = recv(*it,buf,sizeof(buf)-1,MSG_OOB); if(ret < 0) { perror("exception"); } else { buf[ret] = '\0'; printf("%s",buf); } } ++it; } if( FD_ISSET(server_sockfd,&read_fds) ) { //接受连接,并将被接受的远端sock地址信息保存在第二个参数中 int newfd = accept(server_sockfd,(struct sockaddr*)&client_addr,&client_addrlength); if(newfd < 0) { perror("accept"); return -1; } else { connFds.push_back(newfd); max_fd = newfd; //inet_ntoa(struct addr_in) 将IP地址转换为字符串并返回 //只是从监听队列中取出连接,即使客户端已经断开网络连接也会accept成功 printf("accept client_addr %s\n",inet_ntoa(client_addr.sin_addr)); } } } //关闭连接,实际只是socket的引用-1,必须引用为0才会真正关闭 for(int i= 0;i< connFds.size();++i) { close(connFds[i]); } close(server_sockfd); return 0;}
0 0
- select监听多个socket的例子
- socket 的select函数例子
- 3个学习Socket编程的简单例子:TCP Server/Client, Select
- 一个select接收socket数据的例子
- 一个select接收socket数据的例子
- linux socket的select函数例子
- linux socket的select函数例子
- linux socket的select函数例子
- linux socket的select函数例子
- linux socket的select函数例子
- linux socket的select函数例子
- linux socket的select函数例子
- linux socket的select函数例子
- linux socket的select函数例子
- linux socket 的select函数例子
- linux socket的select函数例子
- linux socket的select函数例子
- linux socket的select函数例子
- osg::BillBoard的用法
- 【BZOJ 1618】 [Usaco2008 Nov]Buying Hay 购买干草
- ZooKeeper源码分析:Quorum请求的整个流程
- JavaScript 中的"类"与"实例"
- Android:不同Activity之间的数据传递 (简单的demo)
- select监听多个socket的例子
- 互联网分享希望
- Java 动态代理
- Codeforces Round #285 (Div. 2) C. Misha and Forest
- iOS常用尺寸大小说明
- ssh自动登录工具
- MFC List Control滚动条
- linux编程|fork函数讲解
- 产品经理之原型工具