笔记脑图
作业2
完成局域网CS模型,局域网内一个服务器,多个客户端连接一个服务器,完成局域网聊天(select函数,poll函数,完成TCP并发服务器)。
select函数
cpp
#include <stdio.h>
#include <string.h>
#include <myhead.h>
#define IP "192.168.110.44"
#define PORT 6666
#define BACKLOG 20
int main(int argc, const char *argv[])
{
//创建
int oldfd=socket(AF_INET,SOCK_STREAM,0);
if(oldfd==-1)
{
perror("socket");
return -1;
}
//绑定
struct sockaddr_in server={
.sin_family=AF_INET,
.sin_port=htons(PORT),
.sin_addr.s_addr=inet_addr(IP),
};
if(bind(oldfd,(struct sockaddr *)&server,sizeof(server))==-1)
{
perror("bind");
return -1;
}
//监听
if(listen(oldfd,BACKLOG)==-1)
{
perror("listen");
return -1;
}
//接收通信
struct sockaddr_in client;
socklen_t client_len=sizeof(client);
//1-1定义容器
fd_set readfds,temp;
FD_ZERO(&readfds);
FD_SET(0,&readfds);
FD_SET(oldfd,&readfds);
int maxfd=oldfd;
int newfd;
while(1)//循环连入
{
//监视
temp=readfds;
int res=select(maxfd+1,&temp,NULL,NULL,NULL);
if(res==-1)
{
perror("select");
return -1;
}
if(res==0)
{
printf("超时\n");
continue;
}
//检测谁发生IO操作
int i;
for(i=0;i<=maxfd;i++)
{
if(FD_ISSET(i,&temp))
{
continue;
}
else if(i==oldfd)
{
newfd=accept(i,(struct sockaddr *)&client,&client_len);
FD_SET(newfd,&readfds);
maxfd=newfd>maxfd?newfd:maxfd;
if(newfd==-1)
{
perror("accept");
return -1;
}
printf("%s发来连接请求\n",inet_ntoa(client.sin_addr));
}
else
{
//循环收发
char buff[1024];
memset(buff,0,sizeof(buff));
int len=recv(i,buff,sizeof(buff),0);
if(len==0)
{
close(i);
FD_CLR(i,&readfds);
if(maxfd==i)
{
maxfd--;
}
printf("客户端下线\n");
break;
}
printf("%s\n",buff);
fgets(buff,sizeof(buff),stdin);
send(newfd,buff,sizeof(buff),0);
}
}
}
//关闭
close(oldfd);
return 0;
}
poll函数
cpp
#include <poll.h>
#include <myhead.h>
#define IP "192.168.110.53"
#define PORT 6666
#define BACKLOG 20
int main(int argc, const char *argv[])
{
//创建
int oldfd=socket(AF_INET,SOCK_STREAM,0);
if(oldfd==-1)
{
perror("socket");
return -1;
}
//绑定
struct sockaddr_in server={
.sin_family=AF_INET,
.sin_port=htons(PORT),
.sin_addr.s_addr=inet_addr(IP),
};
if(bind(oldfd,(struct sockaddr *)&server,sizeof(server))==-1)
{
perror("bind");
return -1;
}
//监听
if(listen(oldfd,BACKLOG)==-1)
{
perror("listen");
return -1;
}
//1-1设置结构体检测
struct pollfd fds[100];
fds[0].fd=oldfd;
fds[0].events=POLLIN;
//接收通信
struct sockaddr_in client;
socklen_t client_len=sizeof(client);
int newfd;
//1-2检测描述符
int i;
int count=1;
while(1)
{
int res=poll(fds,100,-1);
if(res==-1)
{
perror("poll");
}
if(res==0)
{
printf("超时\n");
}
if(fds[0].revents==POLLIN)
{
newfd=accept(oldfd,(struct sockaddr *)&client,&client_len);
if(newfd==-1)
{
perror("accept");
return -1;
}
printf("%s发来连接请求\n",inet_ntoa(client.sin_addr));
fds[count].fd=newfd;//创建新描述符
fds[count].events=POLLIN;
count++;
}
//循环收发
for(i=1;i<100;i++)
{
if(fds[i].fd>0&&fds[i].revents==POLLIN)
{
char buff[1024];
memset(buff,0,sizeof(buff));
int len=recv(fds[i].fd,buff,sizeof(buff),0);
if(len==0)
{
printf("客户端下线\n");
close(fds[i].fd);
break;
}
printf("%s\n",buff);
strcat(buff,"5201314");
send(fds[i].fd,buff,sizeof(buff),0);
}
}
}
//关闭
close(fds[0].fd);
return 0;
}