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 8889int 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;
}