1.select模型
| |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <string.h> |
| #include <unistd.h> |
| #include <arpa/inet.h> |
| #include <sys/socket.h> |
| #include <errno.h> |
| #include <sys/select.h> |
| #include <errno.h> |
| #include <vector> |
| |
| int InitServer(const unsigned int port); |
| |
| int main(int argc,char** argv) |
| { |
| int listenfd=InitServer(atoi(argv[1])); |
| if(listenfd==-1) |
| { |
| printf("InitServer failed..\n"); |
| return -1; |
| } |
| |
| std::vector<int> clientfds; |
| |
| fd_set readfdset; |
| FD_ZERO(&readfdset); |
| FD_SET(listenfd,&readfdset); |
| int maxfd; |
| maxfd=listenfd; |
| struct timeval sttime; |
| sttime.tv_sec=30; |
| while(true) |
| { |
| fd_set readfdsetTmp=readfdset; |
| int infds=select(maxfd+1,&readfdsetTmp,NULL,NULL,NULL); |
| if(infds<0) |
| { |
| printf("select error..\n"); |
| perror("select failed: "); |
| break; |
| } |
| else if(infds==0) |
| { |
| printf("timeout..\n"); |
| continue; |
| } |
| else |
| { |
| for(int eventfd=0;eventfd<=maxfd;eventfd++) |
| { |
| if(FD_ISSET(eventfd,&readfdsetTmp)<=0) |
| continue; |
| if(eventfd==listenfd) |
| { |
| |
| struct sockaddr_in client_addr; |
| socklen_t client_addr_size=sizeof(client_addr); |
| int clientfd = accept(listenfd, (struct sockaddr*)&client_addr,(socklen_t*)&client_addr_size); |
| |
| printf("client(%d) connectd..\n",clientfd); |
| FD_SET(clientfd,&readfdset); |
| |
| if(maxfd<clientfd) |
| maxfd=clientfd; |
| clientfds.push_back(clientfd); |
| continue; |
| } |
| else |
| { |
| |
| char buf[1024]; |
| memset(buf,0,sizeof(buf)); |
| size_t isize = recv(eventfd,buf,sizeof(buf),0); |
| if(isize<0) |
| { |
| |
| printf("client(%d) disconneted..\n",eventfd); |
| close(eventfd); |
| for(auto iter=clientfds.begin();iter!=clientfds.end();iter++) |
| { |
| if(*iter==eventfd) |
| clientfd.erase(iter); |
| } |
| FD_CLR(eventfd,&readfdset); |
| if(eventfd==maxfd) |
| { |
| for(int i=maxfd;i>=0;i--) |
| { |
| if(FD_ISSET(eventfd,&readfdset)) |
| { |
| maxfd=eventfd; |
| break; |
| } |
| } |
| } |
| continue; |
| } |
| |
| |
| printf("recv(%d):%s,size=%d\n",eventfd,buf,isize) ; |
| send(eventfd,buf,strlen(buf),0); |
| |
| } |
| |
| } |
| } |
| |
| } |
| return 0; |
| } |
| |
| int InitServer(const unsigned int port) |
| { |
| int sockfd=-1; |
| sockfd = socket(PF_INET, SOCK_STREAM, 0); |
| if(sockfd == -1) return -1; |
| |
| int opt=1; |
| unsigned int len=sizeof(opt); |
| setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, len); |
| |
| struct sockaddr_in server_addr; |
| memset(&server_addr, 0, sizeof(server_addr)); |
| server_addr.sin_family=AF_INET; |
| server_addr.sin_addr.s_addr=htonl(INADDR_ANY); |
| server_addr.sin_port=htons(port); |
| |
| if(bind(sockfd, (struct sockaddr*) &server_addr, sizeof(server_addr)) == -1) |
| { |
| close(sockfd); |
| sockfd=-1; |
| return -1; |
| } |
| |
| if(listen(sockfd, 5) == -1) |
| { |
| close(sockfd); |
| sockfd=-1; |
| return -1; |
| } |
| |
| return sockfd; |
| } |
| |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <string.h> |
| #include <unistd.h> |
| #include <arpa/inet.h> |
| #include <sys/socket.h> |
| #include <errno.h> |
| #include <sys/select.h> |
| #include <netdb.h> |
| |
| |
| bool ConnectServer(int* sockfd, const char* ip, int port); |
| |
| int main(int argc,char** argv) |
| { |
| int serverfd=-1; |
| if(ConnectServer(&serverfd,"127.0.0.1",atoi(argv[1]))==false) |
| { |
| printf("connect failed..\n"); |
| return -1; |
| } |
| printf("connected..\n"); |
| |
| char buf[1024]; |
| while(true) |
| { |
| memset(buf,0,sizeof(buf)); |
| printf("enter input:\n"); |
| scanf("%s",buf); |
| |
| if(send(serverfd,buf,strlen(buf),0)==false) |
| { |
| printf("send error..\n"); |
| return -1; |
| } |
| printf("send:%s\n",buf); |
| |
| memset(buf,0,sizeof(buf)); |
| if(recv(serverfd,buf,sizeof(buf),0)==false) |
| { |
| printf("recv error..\n"); |
| return -1; |
| } |
| printf("recv:%s\n",buf); |
| } |
| |
| return 0; |
| } |
| |
| bool ConnectServer(int* sockfd, const char* ip, int port) |
| { |
| struct sockaddr_in server_addr; |
| memset(&server_addr,0,sizeof(server_addr)); |
| server_addr.sin_family=AF_INET; |
| |
| server_addr.sin_addr.s_addr=inet_addr(ip); |
| server_addr.sin_port=htons(port); |
| |
| *sockfd = socket(PF_INET, SOCK_STREAM, 0); |
| if(*sockfd==-1) |
| { |
| return false; |
| } |
| |
| if(connect(*sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr)) == -1) |
| { |
| close(*sockfd); |
| *sockfd=-1; |
| return false; |
| } |
| |
| return true; |
| } |
2.poll模型
| |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <string.h> |
| #include <unistd.h> |
| #include <arpa/inet.h> |
| #include <sys/socket.h> |
| #include <errno.h> |
| #include <vector> |
| #include <time.h> |
| #include <poll.h> |
| #include <fcntl.h> |
| |
| #define MAXNFDS 1024 |
| |
| int InitServer(const unsigned int port); |
| |
| int main(int argc,char** argv) |
| { |
| int listenfd=InitServer(atoi(argv[1])); |
| printf("listenfd=%d\n",listenfd); |
| if(listenfd==-1) |
| { |
| printf("InitServer failed..\n"); |
| return -1; |
| } |
| |
| |
| int maxfd; |
| struct pollfd fds[MAXNFDS]; |
| for(int i=0;i<MAXNFDS;i++) |
| { |
| fds[i].fd=-1; |
| } |
| |
| fds[listenfd].fd=listenfd; |
| fds[listenfd].events=POLLIN; |
| fds[listenfd].revents=0; |
| maxfd=listenfd; |
| |
| while(1) |
| { |
| int infds=poll(fds,maxfd+1,-1); |
| if(infds<0) |
| { |
| printf("poll error..\n"); |
| perror("poll failed: "); |
| break; |
| } |
| |
| if(infds==0) |
| { |
| printf("timeout..\n"); |
| continue; |
| } |
| |
| |
| for(int eventfd=0;eventfd<=maxfd;eventfd++) |
| { |
| if(fds[eventfd].fd==-1) |
| continue; |
| |
| |
| |
| |
| |
| |
| |
| |
| if((eventfd==listenfd) && (fds[eventfd].revents&POLLIN)) |
| { |
| fds[eventfd].revents=0; |
| struct sockaddr_in client_addr; |
| socklen_t client_addr_size=sizeof(client_addr); |
| int clientfd = accept(listenfd, (struct sockaddr*)&client_addr,&client_addr_size); |
| if(clientfd<0) |
| printf("accept failed..\n"); |
| printf("%ld client(%d) connectd..\n",time(0),clientfd); |
| |
| if(clientfd>MAXNFDS) |
| { |
| printf("clientfd(%d) > MAXNFDS(%d), close client..\n",clientfd,MAXNFDS); |
| close(clientfd); |
| continue; |
| } |
| |
| |
| fds[clientfd].fd=clientfd; |
| fds[clientfd].events=POLLIN; |
| fds[clientfd].revents=0; |
| |
| if(maxfd<clientfd) |
| maxfd=clientfd; |
| printf("maxfd=%d\n",maxfd); |
| continue; |
| } |
| else if(fds[eventfd].revents&POLLIN) |
| { |
| fds[eventfd].revents=0; |
| char buf[1024]; |
| memset(buf,0,sizeof(buf)); |
| size_t isize = recv(eventfd,buf,sizeof(buf),0); |
| if(isize<=0) |
| { |
| printf("%ld client(%d) disconneted..\n",time(0),eventfd); |
| close(eventfd); |
| |
| |
| fds[eventfd].fd=-1; |
| if(eventfd==maxfd) |
| { |
| for(int i=maxfd;i>0;i--) |
| { |
| if(fds[i].fd!=-1) |
| maxfd=i; |
| break; |
| } |
| printf("maxfd=%d\n",maxfd); |
| } |
| continue; |
| } |
| |
| |
| send(eventfd,buf,strlen(buf),0); |
| } |
| } |
| } |
| return 0; |
| } |
| |
| int InitServer(const unsigned int port) |
| { |
| int sockfd=-1; |
| sockfd = socket(PF_INET, SOCK_STREAM, 0); |
| if(sockfd == -1) return -1; |
| |
| int opt=1; |
| unsigned int len=sizeof(opt); |
| setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, len); |
| |
| struct sockaddr_in server_addr; |
| memset(&server_addr, 0, sizeof(server_addr)); |
| server_addr.sin_family=AF_INET; |
| server_addr.sin_addr.s_addr=htonl(INADDR_ANY); |
| server_addr.sin_port=htons(port); |
| |
| if(bind(sockfd, (struct sockaddr*) &server_addr, sizeof(server_addr)) == -1) |
| { |
| close(sockfd); |
| sockfd=-1; |
| return -1; |
| } |
| |
| if(listen(sockfd, 5) == -1) |
| { |
| close(sockfd); |
| sockfd=-1; |
| return -1; |
| } |
| |
| return sockfd; |
| } |
3.epoll模型
| |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <string.h> |
| #include <unistd.h> |
| #include <arpa/inet.h> |
| #include <sys/socket.h> |
| #include <errno.h> |
| #include <vector> |
| #include <time.h> |
| #include <sys/epoll.h> |
| #include <fcntl.h> |
| |
| #define MAXEVENTS 100 |
| |
| int InitServer(const unsigned int port); |
| |
| int main(int argc,char** argv) |
| { |
| int listenfd=InitServer(atoi(argv[1])); |
| printf("listenfd=%d\n",listenfd); |
| if(listenfd==-1) |
| { |
| printf("InitServer failed..\n"); |
| return -1; |
| } |
| |
| |
| int epollfd=epoll_create(1); |
| if(epollfd<0) printf("epoll_create failed..\n"); |
| |
| |
| struct epoll_event ev; |
| ev.data.fd=listenfd; |
| ev.events=EPOLLIN; |
| epoll_ctl(epollfd,EPOLL_CTL_ADD,listenfd,&ev); |
| |
| while(true) |
| { |
| struct epoll_event events[MAXEVENTS]; |
| int infds=epoll_wait(epollfd,events,MAXEVENTS,-1); |
| if(infds<0) |
| { |
| printf("epoll_wait failed..\n"); |
| break; |
| } |
| if(infds==0) |
| { |
| printf("timeout..\n"); |
| break; |
| } |
| |
| |
| for(int i=0;i<infds;i++) |
| { |
| |
| if((events[i].data.fd==listenfd) && (events[i].events&EPOLLIN)) |
| { |
| struct sockaddr_in client_addr; |
| socklen_t client_addr_size=sizeof(client_addr); |
| int clientfd = accept(listenfd, (struct sockaddr*)&client_addr,&client_addr_size); |
| if(clientfd<0) |
| { |
| printf("accept failed..\n"); |
| continue; |
| } |
| |
| |
| memset(&ev,0,sizeof(struct epoll_event)); |
| |
| ev.data.fd=clientfd; |
| ev.events=EPOLLIN; |
| epoll_ctl(epollfd,EPOLL_CTL_ADD,clientfd,&ev); |
| printf("%ld client(%d) connectd..\n",time(0),clientfd); |
| continue; |
| } |
| else if(events[i].events&EPOLLIN) |
| { |
| char buf[1024]; |
| memset(buf,0,sizeof(buf)); |
| size_t isize = recv(events[i].data.fd,buf,sizeof(buf),0); |
| |
| if(isize<=0) |
| { |
| |
| memset(&ev,0,sizeof(struct epoll_event)); |
| ev.data.fd=events[i].data.fd; |
| ev.events=EPOLLIN; |
| epoll_ctl(epollfd,EPOLL_CTL_DEL,events[i].data.fd,&ev); |
| |
| close(events[i].data.fd); |
| printf("%ld client(%d) disconneted..\n",time(0),events[i].data.fd); |
| continue; |
| } |
| |
| printf("client(%d)recv msg:%s,size=%d\n",events[i].data.fd,buf,isize); |
| |
| |
| |
| fd_set tmpfd; |
| FD_ZERO(tmpfd); |
| FD_SET(events[i].data.fd,&tmpfd); |
| if(select(events[i].data.fd+1,0,&tmpfd,0,0)<0) |
| { |
| printf("没有可写数据的fd\n"); |
| return -1; |
| } |
| if(write(events[i].data.fd,buf,strlen(buf))<0) |
| { |
| printf("write failed..\n"); |
| close(events[i].data.fd); |
| return -1; |
| } |
| |
| } |
| } |
| } |
| return 0; |
| } |
| |
| int InitServer(const unsigned int port) |
| { |
| int sockfd=-1; |
| sockfd = socket(PF_INET, SOCK_STREAM, 0); |
| if(sockfd == -1) return -1; |
| |
| int opt=1; |
| unsigned int len=sizeof(opt); |
| setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, len); |
| |
| struct sockaddr_in server_addr; |
| memset(&server_addr, 0, sizeof(server_addr)); |
| server_addr.sin_family=AF_INET; |
| server_addr.sin_addr.s_addr=htonl(INADDR_ANY); |
| server_addr.sin_port=htons(port); |
| |
| if(bind(sockfd, (struct sockaddr*) &server_addr, sizeof(server_addr)) == -1) |
| { |
| close(sockfd); |
| sockfd=-1; |
| return -1; |
| } |
| |
| if(listen(sockfd, 5) == -1) |
| { |
| close(sockfd); |
| sockfd=-1; |
| return -1; |
| } |
| |
| return sockfd; |
| } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)