思维导图
select完成tcp并发服务器模型:
服务器端
#include <myhead.h>
#define SER_PORT 8888
#define SER_IP "192.168.122.153"int main(int argc, const char *argv[])
{int sfd = socket(AF_INET,SOCK_STREAM,0);if(sfd==-1){perror("socket error");return -1;}printf("sfd=%d\n",sfd);int reuse =1;if(setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse))==-1){perror("setsockopt error");return -1;}printf("端口号快速重用成功\n");struct sockaddr_in sin;sin.sin_family=AF_INET;sin.sin_port=htons(SER_PORT);sin.sin_addr.s_addr=inet_addr(SER_IP);if(bind(sfd,(struct sockaddr*)&sin,sizeof(sin))==-1){perror("bind error");return -1;}printf("bind success %s %s %d\n",__FILE__,__func__,__LINE__);if(listen(sfd,128)==-1){perror("listen error");return -1;}printf("listen success %s %s %d\n",__FILE__,__func__,__LINE__);struct sockaddr_in cin; socklen_t socklen = sizeof(cin); int newfd=-1;fd_set readfds,tempfds;FD_ZERO(&readfds);FD_SET(0,&readfds);FD_SET(sfd,&readfds);int maxfd=sfd;struct sockaddr_in cin_arr[1024];while(1){tempfds = readfds;int res = select(maxfd+1,&tempfds,0,0,0);if(res==9){perror("select error");return -1;}else if(res==0){printf("timeout\n");return -1;}for(int cli=0;cli<=maxfd;cli++){if(!FD_ISSET(cli,&tempfds)){continue;}if(cli==0){char wbuf[128]="";scanf("%s",wbuf);printf("触发了终端输入事件---\n");if(strcmp(wbuf,"quit")==0){goto END;}for (int i = 4; i <= maxfd; i++){sendto(i,wbuf,sizeof(wbuf),0,(struct sockaddr*)&cin_arr[i],sizeof(cin_arr[i]));}}else if(cli==sfd){if((newfd =accept(sfd,(struct sockaddr*)&cin,&socklen))==-1){perror("accept error");return -1;}printf("您有一个新的客户端[%s:%d]发来连接请求 success %s %s %d\n",\inet_ntoa(cin.sin_addr),ntohs(cin.sin_port),__FILE__,__func__,__LINE__);cin_arr[newfd]=cin;FD_SET(newfd,&readfds);if(newfd>maxfd){maxfd=newfd;}}else{char buf[128]="";bzero(buf,sizeof(buf));int res=recv(cli,buf,sizeof(buf),0);if(res==0){puts("客户端已经下线");close(cli);FD_CLR(cli,&readfds);for(int i=maxfd;i>=sfd;i--){if(FD_ISSET(i,&readfds)){maxfd=i;break;}}continue;}printf("[%s:%d] : %s\n",inet_ntoa(cin_arr[cli].sin_addr),ntohs(cin_arr[cli].sin_port),buf);strcat(buf,"=-=");send(cli,buf,sizeof(buf),0);printf("发送成功\n");}}}END:close(sfd);return 0;
}
#include <myhead.h>
#define SER_PORT 8888
#define SER_IP "192.168.122.153"
#define CLI_PORT 6666
#define CLI_IP "192.168.122.153"int main(int argc, const char *argv[])
{int cfd = socket(AF_INET,SOCK_STREAM,0);if(cfd==-1){perror("socket error");return -1;}printf("cfd=%d\n",cfd);
struct sockaddr_in sin;sin.sin_family=AF_INET;sin.sin_port=htons(SER_PORT);sin.sin_addr.s_addr=inet_addr(SER_IP);if(connect(cfd,(struct sockaddr*)&sin,sizeof(sin))==-1){perror("");return -1;}printf("链接成功\n");fd_set readfds,tempfds;FD_ZERO(&readfds);FD_SET(0,&readfds);FD_SET(cfd,&readfds);char buf[128]="";while(1){tempfds = readfds;int res = select(cfd+1,&tempfds,0,0,0);if(res==-1){perror("select error");return -1;}else if(res==0){printf("timeout\n");return -1;}if(FD_ISSET(0,&tempfds)){bzero(buf,sizeof(buf));printf("请输入>>>\n");fgets(buf,sizeof(buf),stdin);buf[strlen(buf)-1]=0;send(cfd,buf,sizeof(buf),0);printf("发送成功\n");if(strcmp(buf,"quit")==0){break;}}else if(FD_ISSET(cfd,&tempfds)){recv(cfd,buf,sizeof(buf),0);printf("[%s:%d]:%s\n",SER_IP,SER_PORT,buf);}}close(cfd);return 0;
}
实现结果
poll完成tcp并发服务器模型:
#include <myhead.h>
#define SER_PORT 8888
#define SER_IP "192.168.122.153"int main(int argc, const char *argv[])
{int sfd = socket(AF_INET,SOCK_STREAM,0);if(sfd==-1){perror("socket error");return -1;}printf("sfd=%d\n",sfd);int reuse =1;if(setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse))==-1){perror("setsockopt error");return -1;}printf("端口号快速重用成功\n");struct sockaddr_in sin;sin.sin_family=AF_INET;sin.sin_port=htons(SER_PORT);sin.sin_addr.s_addr=inet_addr(SER_IP);if(bind(sfd,(struct sockaddr*)&sin,sizeof(sin))==-1){perror("bind error");return -1;}printf("bind success %s %s %d\n",__FILE__,__func__,__LINE__);if(listen(sfd,128)==-1){perror("listen error");return -1;}printf("listen success %s %s %d\n",__FILE__,__func__,__LINE__);struct sockaddr_in cin; socklen_t socklen = sizeof(cin); int newfd=-1;struct pollfd pfd[10];pfd[0].fd=0;pfd[0].events=POLLIN;pfd[1].fd=sfd;pfd[1].events=POLLIN;int client_num=0;struct sockaddr_in cin_arr[1024];while(1){int res=poll(pfd,client_num+2,-1);if(res==-1){perror("poll error");return -1;}else if(res==0){printf("timeout\n");return -1;}if(pfd[0].revents==POLLIN){char wbuf[128]="";scanf("%s",wbuf);printf("触发了终端输入事件---\n");if(strcmp(wbuf,"quit")==0){break;}for (int i = 4; i <= client_num+3; i++){send(i,wbuf,sizeof(wbuf),0);}}if(pfd[1].revents==POLLIN){if((newfd =accept(sfd,(struct sockaddr*)&cin,&socklen))==-1){perror("accept error");return -1;}printf("您有一个新的客户端[%s:%d]发来连接请求 success %s %s %d\n",\inet_ntoa(cin.sin_addr),ntohs(cin.sin_port),__FILE__,__func__,__LINE__);client_num++;pfd[1+client_num].fd=newfd;pfd[1+client_num].events=POLLIN;printf("客户端连接成功\n");}for(int cli=0;cli<client_num;cli++){if(pfd[cli+2].revents==POLLIN){char buf[128]="";bzero(buf,sizeof(buf));int res=recv(pfd[cli+2].fd,buf,sizeof(buf),0);if(res==0){puts("客户端已经下线");close(pfd[cli+2].fd);client_num--;continue;}printf("收到消息:%s\n",buf);strcat(buf,"=-=");send(pfd[cli+2].fd,buf,sizeof(buf),0);printf("发送成功\n");}}}close(sfd);return 0;
}
#include <myhead.h>
#define SER_PORT 8888
#define SER_IP "192.168.122.153"
#define CLI_PORT 6666
#define CLI_IP "192.168.122.153"int main(int argc, const char *argv[])
{int cfd = socket(AF_INET,SOCK_STREAM,0);if(cfd==-1){perror("socket error");return -1;}printf("cfd=%d\n",cfd);
struct sockaddr_in sin;sin.sin_family=AF_INET;sin.sin_port=htons(SER_PORT);sin.sin_addr.s_addr=inet_addr(SER_IP);if(connect(cfd,(struct sockaddr*)&sin,sizeof(sin))==-1){perror("");return -1;}printf("链接成功\n");struct pollfd pfd[2];pfd[0].fd=0;pfd[0].events=POLLIN;pfd[1].fd=cfd;pfd[1].events=POLLIN;char buf[128]="";while(1){int res=poll(pfd,2,-1);if(res==-1){perror("poll error");return -1;}else if(res==0){printf("timeout\n");return -1;}if(pfd[0].revents==POLLIN){bzero(buf,sizeof(buf));printf("请输入:");fgets(buf,sizeof(buf),stdin);buf[strlen(buf)-1]=0;send(cfd,buf,sizeof(buf),0);printf("发送成功\n");if(strcmp(buf,"quit")==0){break;}}if(pfd[1].revents==POLLIN){recv(cfd,buf,sizeof(buf),0);printf("[%s:%d]:%s\n",SER_IP,SER_PORT,buf);}}close(cfd);return 0;
}
实现结果