select客户端
#include<myhead.h>
#define POFT 9999 //端口号
#define IP "192.168.114.105" //IP地址
#define SPORT 8888
#define SIP "192.168.114.105"
int main(int argc, const char *argv[])
{
//1.创建用于连接的套接字
int sfd=socket(AF_INET,SOCK_STREAM,0);
if(sfd==-1)
{
perror("socket error");
}
//2.绑定IP地址和端口号
//2.1填充要绑定的地址信息结构体
struct sockaddr_in sin;
sin.sin_family = AF_INET;//IPv4
sin.sin_port =htons( POFT);//port is two byte客户端端口
sin.sin_addr.s_addr = inet_addr(IP);//客户端IP地址
//重用端口
int suor=1;
setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,&suor,sizeof(suor));
//绑定
if( bind(sfd,(struct sockaddr*)&sin,sizeof(sin))==-1)
{
perror("bind error");
}
//定义信息结构体
struct sockaddr_in cin;
cin.sin_family = AF_INET; //客户端地址信息
cin.sin_addr.s_addr=inet_addr(SIP);
cin.sin_port=htons(SPORT);
int res=0;
int ret=0;
int num=0;
//定义容器
fd_set readfds,temfds;
//清空readfds
FD_ZERO(&readfds);
//将要检测的文件描述符写入集合
FD_SET(sfd,&readfds);
FD_SET(0,&readfds);
char buf1[128]="";
char buf2[128]="";
res=connect(sfd,(struct sockaddr*)&cin,sizeof(cin));
if(res==-1)
{
perror("connect error");
}
printf("connect success:_%d_%s_%s_\n",__LINE__,__FILE__,__func__);
while(1)
{
temfds=readfds;
bzero(buf1,sizeof(buf1));
bzero(buf2,sizeof(buf2));
res=select(sfd+1,&temfds,NULL,NULL,NULL);
printf("res=%d\n",res);
if(res==-1)
{
perror("select error");
}
else if(res==0)
{
printf("time out\n");
}
if(FD_ISSET(0,&temfds))
{
fgets(buf1,sizeof(buf1),stdin);
buf1[strlen(buf1)-1]='\0';
//向服务器发送数据
send(sfd,buf1,sizeof(buf1),0);
if(strcmp(buf1,"quit")==0)
{
break;
}
}
if(FD_ISSET(sfd,&temfds))
{
//接受服务器数据
ret=recv(sfd,buf2,sizeof(buf2),0);
if(ret==0)
{
printf("客户端下线\n");
break;
}
printf("读取的数据:%s\n",buf2);
}
}
close(sfd);
return 0;
}
select服务器
#include<myhead.h>
#define POFT 8888 //端口号
#define IP "192.168.114.105" //IP地址
int main(int argc, const char *argv[])
{
//1.创建用于连接的套接字
int sfd=socket(AF_INET,SOCK_STREAM,0);
if(sfd==-1)
{
perror("socket error");
}
//2.绑定IP地址和端口号
//2.1填充要绑定的地址信息结构体
struct sockaddr_in sin;
sin.sin_family = AF_INET;//IPv4
sin.sin_port =htons( POFT);//port is two byte
sin.sin_addr.s_addr = inet_addr(IP);//IP地址
//重用端口
int suor=1;
setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,&suor,sizeof(suor));
//2.2绑定
if( bind(sfd,(struct sockaddr*)&sin,sizeof(sin))==-1)
{
perror("bind error");
}
//3.设定套接字为被动的监听状态
if(listen(sfd,128)==-1)
{
perror("listen error");
}
printf("listen success _%d_%s_%s_\n",__LINE__,__FILE__,__func__);
//4.等待客户端请求,如果存在新的客户端请求,创建新的用于通信的套接字
//4.1定义信息结构体
struct sockaddr_in cin;
cin.sin_family = AF_INET; //客户端地址信息
socklen_t socklen=sizeof(cin);
fd_set readfds,temfds;
//清空容器内的内容
FD_ZERO(&readfds);
//将要检测的文件描述符放入集合
FD_SET(sfd,&readfds);
FD_SET(0,&readfds);
//定义容器
char buf[128]="";
int newfd=-1;
int maxfd=sfd;
struct sockaddr_in saveCin[1024];
int res=0;
while(1)
{
//复制集合内容
temfds=readfds;
//select阻塞
res=select(maxfd+1,&temfds,NULL,NULL,NULL);
if(res==-1)
{
perror("select error");
}
else if(res==0)
{
printf("time out\n");
}
//遍历所有集合中文件描述符
for(int i=0;i<=maxfd;i++)
{
if(!FD_ISSET(i,&temfds))
{
continue;
}
//判断sfd是否在集合里
if(i==sfd)
{
newfd=accept(sfd,(struct sockaddr *)&cin,&socklen);
if(newfd==-1)
{
perror("newfd error");
}
printf("accept success:_%d_%s_%s_\n",__LINE__,__FILE__,__func__);
//将newfd的内容放入readfds中
FD_SET(newfd,&readfds);
//更新maxfd
if(newfd>maxfd)
{
maxfd=newfd;
}
//将最新客户端的套接字放入数组下标为new的位置
saveCin[newfd]=cin;
printf("newfd=%d\n",newfd);
}
else if(i==0) //判断是否为终端你输入
{
char buf1[128]="";
bzero(buf,sizeof(buf));
//从终端获取数据
fgets(buf,sizeof(buf),stdin);
buf[strlen(buf)-1]='\0';
printf("触发输入事件:%s\n",buf);
sprintf(buf1,"%s%s","系统信息:",buf);
//将数据发送给所有客户端
for(int j=4;j<=maxfd;j++)
{
send(j,buf1,sizeof(buf1),0);
}
}
else{
char buf[128]="";
bzero(buf,sizeof(buf));
//读取客户端信息
int ret=recv(i,buf,sizeof(buf),0);
//判断接受的结果
printf("ret=%d\n",ret);
if(ret==0)
{
printf("客户端已经下线\n");
close(i);//关闭通信的套接字
//删除当前文件描述符
FD_CLR(i,&readfds);
//更新maxfd
for(int j=maxfd;j>=0;j--)
{
if(FD_ISSET(j,&readfds))
{
maxfd=j;
break;
}
}
continue;//判断下一个
}else if(res<0)
{
perror("recv errro");
}
printf("[%s:%d]:%s\n",inet_ntoa(saveCin[i].sin_addr),ntohs(saveCin[i].sin_port),buf);
strcat(buf,"*_*");
send(i,buf,sizeof(buf),0);
}
}
}
close(sfd);
return 0;
}
成果图
poll服务器
#include<myhead.h>
#define POFT 8888 //端口号
#define IP "192.168.114.105" //IP地址
int main(int argc, const char *argv[])
{
//1.创建用于连接的套接字
int sfd=socket(AF_INET,SOCK_STREAM,0);
if(sfd==-1)
{
perror("socket error");
}
//2.绑定IP地址和端口号
//2.1填充要绑定的地址信息结构体
struct sockaddr_in sin;
sin.sin_family = AF_INET;//IPv4
sin.sin_port =htons( POFT);//port is two byte
sin.sin_addr.s_addr = inet_addr(IP);//IP地址
//重用端口
int suor=1;
setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,&suor,sizeof(suor));
//2.2绑定
if( bind(sfd,(struct sockaddr*)&sin,sizeof(sin))==-1)
{
perror("bind error");
}
//3.设定套接字为被动的监听状态
if(listen(sfd,128)==-1)
{
perror("listen error");
}
printf("listen success _%d_%s_%s_\n",__LINE__,__FILE__,__func__);
//4.等待客户端请求,如果存在新的客户端请求,创建新的用于通信的套接字
//4.1定义信息结构体
struct sockaddr_in cin;
cin.sin_family = AF_INET; //客户端地址信息
socklen_t socklen=sizeof(cin);
//定义容器
char buf[128]="";
char buf1[128]="";
int newfd=-1;
int maxfd=sfd;
//将集合管理描述符放入
struct pollfd fds[1024];
//将标准输入放入集合
fds[0].fd=0;
fds[0].events=POLLIN;
//将sfd放入集合
fds[1].fd=0;
fds[1].events=POLLIN;
//创建存放客户端的结构体数组
struct sockaddr_in savecin[1024];
int res;
while(1)
{
//阻塞函数
res=poll(fds,maxfd,-1);
if(res==-1)
{
perror("poll error");
}
else if(res ==0)
{
perror("time out\n");
}
if(fds[1].revents==POLLIN)
{
newfd=accept(sfd,(struct sockaddr *)&cin,&socklen);
if(newfd==-1)
{
perror("newfd error");
}
printf("accept success:_%d_%s_%s_\n",__LINE__,__FILE__,__func__);
//将newfd的内容放入readfds中
fds[newfd].fd=newfd;
fds[newfd].events=POLLIN;
//更新maxfd
if(newfd>maxfd)
{
maxfd=newfd;
}
//将最新客户端的套接字放入数组下标为new的位置
savecin[newfd]=cin;
printf("newfd=%d\n",newfd);
}
else if(fds[0].revents==POLLIN) //判断是否为终端你输入
{
bzero(buf,sizeof(buf));
//从终端获取数据
fgets(buf,sizeof(buf),stdin);
buf[strlen(buf)-1]='\0';
printf("触发输入事件:%s\n",buf);
sprintf(buf1,"%s%s","系统信息:",buf);
//将数据发送给所有客户端
for(int j=4;j<=maxfd;j++)
{
send(j,buf1,sizeof(buf1),0);
}
}
//清空字符串
bzero(buf,sizeof(buf));
//读取客户端信息
int ret=recv(newfd,buf,sizeof(buf),0);
//判断接受的结果
printf("ret=%d\n",ret);
if(ret==0)
{
printf("客户端已经下线\n");
break;
}
else if(res<0)
{
perror("recv error");
}
printf("[%s:%d]:%s\n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_port),buf);
strcat(buf,"*_*");
send(newfd,buf,sizeof(buf),0);
}
close(sfd);
return 0;
}
poll客户端
#include<myhead.h>
#define POFT 9999 //端口号
#define IP "192.168.114.105" //IP地址
#define SPORT 8888
#define SIP "192.168.114.105"
int main(int argc, const char *argv[])
{
//1.创建用于连接的套接字
int sfd=socket(AF_INET,SOCK_STREAM,0);
if(sfd==-1)
{
perror("socket error");
}
//2.绑定IP地址和端口号
//2.1填充要绑定的地址信息结构体
struct sockaddr_in sin;
sin.sin_family = AF_INET;//IPv4
sin.sin_port =htons( POFT);//port is two byte客户端端口
sin.sin_addr.s_addr = inet_addr(IP);//客户端IP地址
//重用端口
int suor=1;
setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,&suor,sizeof(suor));
//绑定
if( bind(sfd,(struct sockaddr*)&sin,sizeof(sin))==-1)
{
perror("bind error");
}
//定义信息结构体
struct sockaddr_in cin;
cin.sin_family = AF_INET; //客户端地址信息
cin.sin_addr.s_addr=inet_addr(SIP);
cin.sin_port=htons(SPORT);
int res=0;
int ret=0;
int num=0;
//定义一个集合管理零号文件描述符和cfd
struct pollfd fds[2];
//将0号描述符放入
fds[0].fd=0;
fds[0].events=POLLIN;
//sfd描述符放入
fds[1].fd=sfd;
fds[1].events=POLLIN;
char buf1[128]="";
char buf2[128]="";
res=connect(sfd,(struct sockaddr*)&cin,sizeof(cin));
if(res==-1)
{
perror("connect error");
}
printf("connect success:_%d_%s_%s_\n",__LINE__,__FILE__,__func__);
while(1)
{
bzero(buf1,sizeof(buf1));
bzero(buf2,sizeof(buf2));
res=poll(fds,2,-1);
printf("res=%d\n",res);
if(res==-1)
{
perror("poll error");
}
else if(res==0)
{
printf("time out\n");
}
if(fds[0].revents==POLLIN)
{
fgets(buf1,sizeof(buf1),stdin);
buf1[strlen(buf1)-1]='\0';
//向服务器发送数据
send(sfd,buf1,sizeof(buf1),0);
if(strcmp(buf1,"quit")==0)
{
break;
}
}
if(fds[1].revents==POLLIN)
{
//接受服务器数据
ret=recv(sfd,buf2,sizeof(buf2),0);
if(ret==0)
{
printf("客户端下线\n");
break;
}
printf("读取的数据:%s\n",buf2);
}
}
close(sfd);
return 0;
}
成果图