1> 使用select完成TCP客户端程序
客户端:
#include<myhead.h>#define FPORT 9999
#define FIP "192.168.125.130"#define KPORT 6666
#define KIP "192.168.125.130"int main(int argc, const char *argv[])
{//创建套接字文件描述符int cfd = 0;if((cfd = socket(AF_INET,SOCK_STREAM,0)) == -1){perror("socket error");return -1;}//允许重复引用int reuse = 1;if(setsockopt(cfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse)) == -1){perror("setsockopt error");return -1;}//绑定客服端struct sockaddr_in sin;sin.sin_family = AF_INET;sin.sin_port = htons(KPORT);sin.sin_addr.s_addr = inet_addr(KIP);if(bind(cfd,(struct sockaddr*)&sin,sizeof(sin)) == -1){perror("bind error");return -1;}//连接服务器struct sockaddr_in cin;cin.sin_family = AF_INET;cin.sin_port = htons(FPORT);cin.sin_addr.s_addr = inet_addr(FIP);if(connect(cfd,(struct sockaddr*)&cin,sizeof(cin)) == -1){perror("connect");return -1;}//定义检测文件描述符的集合fd_set readfd;//清空集合FD_ZERO(&readfd);//将cfd和0加入集合FD_SET(cfd,&readfd);FD_SET(0,&readfd);char buf[128] = "";int res = -1;fd_set tempfd;while(1){tempfd = readfd;res = select(cfd+1,&tempfd,NULL,NULL,NULL);if(res < 0){perror("select error");return -1;}else if(res == 0){printf("time out\n");return -1;}//下面为处理的处理描述符if(FD_ISSET(0,&tempfd)){bzero(buf,sizeof(buf));fgets(buf,sizeof(buf),stdin);buf[strlen(buf)-1]=0;send(cfd,buf,sizeof(buf),0);printf("客服端输入为%s\n",buf);}if(FD_ISSET(cfd,&tempfd)){bzero(buf,sizeof(buf));int res = recv(cfd,buf,sizeof(buf),0);if(res == 0){printf("服务器下线\n");break;}printf("服务器发来的消息为%s\n",buf);}}close(cfd);return 0;
}
服务器:
#include<myhead.h>
#define PORT 9999
#define IP "192.168.125.130"int main(int argc, const char *argv[])
{int sfd = -1;if((sfd = socket(AF_INET,SOCK_STREAM,0)) == -1){perror("socket");return -1;}int reuse = 1;if(setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse)) == -1){perror("setsockopt error");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(bind(sfd,(struct sockaddr*)&sin,sizeof(sin)) == -1){perror("bind error");return -1;}if(listen(sfd,128) == -1){perror("listen error");return -1;}struct sockaddr_in cin;socklen_t socklen = sizeof(cin);int newfd = -1;char buf[128] = "";fd_set readfds;FD_ZERO(&readfds);FD_SET(sfd,&readfds);FD_SET(0,&readfds);int res = 0;fd_set tempfds;int maxfd = sfd;char rbuf[128]="";struct sockaddr_in arr_cin[1024];while(1){tempfds = readfds;res = select(maxfd+1,&tempfds,NULL,NULL,NULL);if(res == -1){perror("select error");return -1;}else if(res == 0){printf("time out\n");return -1;}for(int index=0;index<=maxfd;index++){if(!FD_ISSET(index,&tempfds)){continue;}if(index == sfd){if((newfd = accept(sfd,(struct sockaddr*)&cin,&socklen)) == -1){perror("accept");return -1;}arr_cin[newfd] =cin;printf("[%s:%d]链接成功,newfd = %d\n\n",inet_ntoa(arr_cin[newfd].sin_addr),ntohs(arr_cin[newfd].sin_port),newfd);FD_SET(newfd,&readfds);if(newfd > maxfd){maxfd = newfd;}}else if(index == 0){scanf("%s",buf);printf("%s\n",buf);}else{bzero(rbuf,sizeof(rbuf));int res = recv(index,rbuf,sizeof(rbuf),0);if(res == 0){printf("客户端下线\n");close(index);FD_CLR(index,&readfds);for(int i =maxfd;i>0;i--){if(FD_ISSET(i,&readfds)){maxfd = i;break;}}continue;}printf("[%s:%d] :%s\n",inet_ntoa(arr_cin[index].sin_addr),ntohs(arr_cin[index].sin_port),rbuf);strcat(rbuf,"*_*");send(index,rbuf,sizeof(rbuf),0);}}}close(sfd);return 0;
}
效果图:
2> 使用poll完成TCP并发服务器
客户端:
#include<myhead.h>
#define SERPORT 9999
#define SERIP "192.168.125.130"#define CLIPORT 6666
#define CLIIP "192.168.125.130"int main(int argc, const char *argv[])
{int cfd = -1;if((cfd = socket(AF_INET,SOCK_STREAM,0)) == -1){perror("socket error");return -1;}printf("cfd = %d\n",cfd);int reuse = 1;if(setsockopt(cfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse)) == -1){perror("setsockopt error");return -1;}struct sockaddr_in sin;sin.sin_family = AF_INET;sin.sin_port = htons(CLIPORT);sin.sin_addr.s_addr = inet_addr(CLIIP);if(bind(cfd,(struct sockaddr*)&sin,sizeof(sin)) == -1){perror("bind error");return -1;}struct sockaddr_in cin;cin.sin_family = AF_INET;cin.sin_port = htons(SERPORT);cin.sin_addr.s_addr = inet_addr(SERIP);if(connect(cfd,(struct sockaddr*)&cin,sizeof(cin)) == -1){perror("connect error");return -1;}struct pollfd fds[2];fds[0].fd = 0;fds[0].events = POLLIN;fds[1].fd = cfd;fds[1].events = POLLIN;int res = -1;char wbuf[128] = "";while(1){res = poll(fds,2,-1);if(res < 0){perror("poll error");return -1;}else if(res == 0){printf("time out \n");return -1;}if(fds[0].revents == POLLIN){bzero(wbuf,sizeof(wbuf));fgets(wbuf,sizeof(wbuf),stdin);wbuf[strlen(wbuf)-1]=0;send(cfd,wbuf,sizeof(wbuf),0);}if(fds[1].revents == POLLIN){bzero(wbuf,sizeof(wbuf));int res = recv(cfd,wbuf,sizeof(wbuf),0);if(res == 0){printf("服务器已下线\n");break;}printf("[%s:%d]:%s\n",SERIP,SERPORT,wbuf);}}close(cfd);return 0;
}
服务器:
效果图: