思维导图
![](https://i-blog.csdnimg.cn/blog_migrate/13ed05c02c1745422ea5c081f3fcd756.jpeg)
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;
}
实现结果
![9ea4193ec0726eea426720a854d4b9c.png](https://i-blog.csdnimg.cn/blog_migrate/96d6ced67423a07d26e94c92c1f133cf.png)
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;
}
实现结果
![88b1249f3882e2217ec0b8afa3dd55e.png](https://i-blog.csdnimg.cn/blog_migrate/6f129c6c408217206d7f9974e1d98edd.png)