poll客户端
#include <myhead.h>
#define IP "192.168.38.128"
#define PORT 8889
int main(int argc, const char *argv[])
{
//创建套接字
int cfd = socket(AF_INET,SOCK_STREAM,0);
if(cfd == -1)
{
perror("cfd");
return -1;
}
//绑定
//......
//连接服务端
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(PORT);
sin.sin_addr.s_addr = inet_addr(IP);
if(connect(cfd,(struct sockaddr*)&sin,sizeof(sin))==-1)
{
perror("connect");
return -1;
}
//定义poll结构体并填充
struct pollfd pfd[2];
pfd[0].fd = 0;
pfd[0].events = POLLIN;
pfd[1].fd = cfd;
pfd[1].events = POLLIN;
//poll多路复用,等待事件,设为永远阻塞
char buf[128];
while(1)
{
int res = poll(pfd,2,-1);
if(res == -1)
{
printf("poll error\n");
return -1;
}
if(pfd[0].revents == POLLIN)
{
scanf("%s",buf);
if(strcmp(buf,"quit")==0)
{
break;
}
send(cfd,buf,sizeof(buf),0);
}
if(pfd[1].revents==POLLIN)
{
bzero(buf,sizeof(buf));
recv(cfd,buf,sizeof(buf),0);
printf("服务端发来消息:%s\n",buf);
}
}
close(cfd);
return 0;
}
select服务端
#include <myhead.h>
#define IP "192.168.38.128"
#define PROT 8889
int main(int argc, const char *argv[])
{
//创建套接字
int sfd = socket(AF_INET,SOCK_STREAM,0);
if(sfd == -1)
{
perror("sfd");
return -1;
}
//端口快速重用
int opt = 1;
if (setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt))==-1)
{
perror("setsockopt");
exit(EXIT_FAILURE);
}
//绑定服务端
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(PROT);
sin.sin_addr.s_addr = inet_addr(IP);
if(bind(sfd,(struct sockaddr*)&sin,sizeof(sin))==-1)
{
perror("bind");
return 0;
}
//监听
if(listen(sfd,228)==-1)
{
perror("listen");
return 0;
}
//创建结构体接收客户端信息
struct sockaddr_in cin;
socklen_t len = sizeof(cin);
int newfd = -1;
//创建描述符集合
fd_set readfd,tempfd;
//清空集合
FD_ZERO(&readfd);
//添加到集合
FD_SET(0,&readfd);
FD_SET(sfd,&readfd);
//保存最大描述符
int maxfd = sfd;
//创建一个套接字结构体数组,存储客户端描述符
struct sockaddr_in cin_arr[1024];
while(1)
{
tempfd = readfd;
//阻塞等待事件发生
int res = select(maxfd+1,&tempfd,NULL,NULL,NULL);
if(res == 0)
{
printf("time out\n");
return -1;
}
else if(res == -1)
{
printf("error\n");
return -1;
}
//事件发生
for(int i=0;i<=maxfd;i++)
{
if(!FD_ISSET(i,&tempfd))
{
continue;
}
//客户端连接事件
if(i==sfd)
{
newfd = accept(sfd,(struct sockaddr*)&cin,&len);
if(newfd == -1)
{
perror("newfd");
return -1;
}
printf("[%s:%d]客户端已连接\n",\
inet_ntoa(cin.sin_addr),ntohs(cin.sin_port));
//添加到集合并存储客户端描述符
FD_SET(newfd,&readfd);
cin_arr[newfd]=cin;
//更新最大描述符
if(maxfd < newfd)
{
maxfd = newfd;
}
}
//终端输入事件
else if(i == 0)
{
char buf[128];
scanf("%s",buf);
printf("终端打印:%s\n",buf);
}
//数据收发事件
else
{
char buf[128];
bzero(buf, 128);
int res = recv(i,buf,128,0);
//客户端退出
if(res == 0)
{
printf("客户端已下线\n");
close(i);
//清除当前客户端描述符
FD_CLR(i,&readfd);
//重新获取最大描述符
for(int j = maxfd;j>sfd;j--)
{
if(FD_ISSET(j,&readfd))
{
maxfd = j;
//找到最大描述符后跳出循环不再寻找
break;
}
}
continue;
}
printf("客户端发来消息:%s\n",buf);
}
}
}
close(sfd);
return 0;
}