思维导图
使用IO多路复用实现并发
select实现TCP服务器端
#include <myhead.h>#define SER_IP "192.168.125.112"
#define SER_PORT 8888int main(int argc, const char *argv[])
{int sfd=socket(AF_INET,SOCK_STREAM,0);if(sfd == -1){perror("socket error");return -1;}struct sockaddr_in sin;sin.sin_family=AF_INET;sin.sin_addr.s_addr=inet_addr(SER_IP);sin.sin_port=htons(SER_PORT);if(bind(sfd,(struct sockaddr*)&sin,sizeof(sin)) == -1){perror("bind error");return -1;}printf("bind success\n");if(listen(sfd,128) == -1){perror("listen error");return -1;}printf("listen success");struct sockaddr_in cin;socklen_t addrlen=sizeof(cin);fd_set readfds,tempfds;FD_ZERO(&readfds);FD_SET(sfd,&readfds);FD_SET(0,&readfds);struct sockaddr_in cin_arr[1024];int newfd=0;int maxfd=sfd;while(1){tempfds=readfds;int res=select(maxfd+1,&tempfds,NULL,NULL,NULL);if(res == -1){perror("select error");return -1;}else if(res == 0){printf("timeout\n");return -1;}for(int i=0;i<=maxfd;i++){if(!FD_ISSET(i,&tempfds))continue;if(i == sfd){newfd=accept(i,(struct sockaddr*)&cin,&addrlen);if(newfd == -1){perror("accept error");return -1;}printf("[%s:%d]发来请求\n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_port));if(newfd>=maxfd)maxfd=newfd;FD_SET(newfd,&readfds);cin_arr[newfd]=cin;}else if(i == 0){char buf[128]="";bzero(buf,sizeof(buf));fgets(buf,sizeof(buf),stdin);buf[strlen(buf)-1]=0;printf("输入的信息为:%s\n",buf);for(int k=4;k<=maxfd;k++)send(k,buf,strlen(buf),0);}else{char rbuf[128]="";int res=recv(i,rbuf,sizeof(rbuf),0);if(res == 0){printf("客户端已下线\n");close(i);FD_CLR(i,&readfds);for(int j=maxfd;j>=sfd;j++){if(FD_ISSET(j,&readfds)){maxfd=j;break;}}continue;}printf("[%s:%d]:%s\n",inet_ntoa(cin_arr[i].sin_addr),ntohs(cin_arr[i].sin_port),rbuf);for(int k=4;k<=maxfd;k++){if(k != i)send(k,rbuf,strlen(rbuf),0);}}}}close(sfd);return 0;
}
poll实现TCP客户端
#include <myhead.h>#define SER_IP "192.168.125.112"
#define SER_PORT 8888
#define CLI_IP "192.168.125.112"
#define CLI_PORT 7777int main(int argc, const char *argv[])
{int cfd=socket(AF_INET,SOCK_STREAM,0);if(cfd == -1){perror("socket error");return -1;}struct sockaddr_in cin;cin.sin_family=AF_INET;cin.sin_addr.s_addr=inet_addr(CLI_IP);cin.sin_port=htons(CLI_PORT);if(bind(cfd,(struct sockaddr*)&cin,sizeof(cin)) == -1){perror("bind error");return -1;}printf("bind success\n");struct sockaddr_in sin;sin.sin_family=AF_INET;sin.sin_addr.s_addr=inet_addr(SER_IP);;sin.sin_port=htons(SER_PORT);if(connect(cfd,(struct sockaddr*)&sin,sizeof(sin)) == -1){perror("connect error");return -1;}printf("connect success\n");struct pollfd pfd[2];pfd[0].fd=0;pfd[0].events=POLLIN;pfd[1].fd=cfd;pfd[1].events=POLLIN;char wbuf[128]="";char rbuf[128]="";while(1){int res=poll(pfd,2,-1);if(res == -1){perror("poll error");return -1;}else if(res == 0){printf("timeout");return -1;}if(pfd[0].revents == POLLIN){bzero(wbuf,sizeof(wbuf));printf("请输入:");fgets(wbuf,sizeof(wbuf),stdin);wbuf[strlen(wbuf)-1]=0;send(cfd,wbuf,strlen(wbuf),0);printf("发送成功\n");}if(pfd[1].revents == POLLIN){bzero(rbuf,sizeof(rbuf));recv(cfd,rbuf,sizeof(rbuf),0);printf("读取的内容为:%s\n",rbuf);}}close(cfd);return 0;
}