1.用select实现TCP客户端程序
#include <head.h>
#define PORT 9999 // 服务器端口号
#define IP "192.168.125.74" // 服务器IP地址#define CIP "192.168.125.74" // 客户端
#define CPORT 6666int main(int argc, const char* argv[])
{// 创建套接字int cfd = -1;if ((cfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {perror("socket error\n");return -1;}// 端口快速重用int reus = 1;if ((reus = setsockopt(cfd, SOL_SOCKET, SO_REUSEADDR, &reus, sizeof(reus))) == -1) {perror("setsockopt error\n");return -1;}// 定义地址信息结构体struct sockaddr_in cin;cin.sin_family = AF_INET;cin.sin_port = htons(CPORT);cin.sin_addr.s_addr = inet_addr(CIP);// 绑定(非必须)if (bind(cfd, (struct sockaddr*)&cin, sizeof(cin)) == -1) {perror("bind error\n");return -1;}printf("bind success\n");// 定义服务器地址信息结构体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 error");return -1;}// 定义检测描述符集合fd_set readfds;// 清0FD_ZERO(&readfds);// 将0、cfd放入集合FD_SET(0, &readfds);FD_SET(cfd, &readfds);// 收发数据char buf[128] = ""; // 容器fd_set temp; //int res = -1;while (1) {temp = readfds;res = select(cfd + 1, &temp, 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, &temp)) {bzero(buf, sizeof(buf)); // 清零fgets(buf, sizeof(buf), stdin);buf[strlen(buf) - 1] = 0;send(cfd, buf, sizeof(buf), 0);}if (FD_ISSET(cfd, &temp)) {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;
}
2.用poll实现服务器
#include <head.h>
#define PORT 9999
#define IP "192.168.125.74"
int main(int argc, const char *argv[])
{int sfd=-1;if((sfd=socket(AF_INET,SOCK_STREAM,0))==-1){perror("socket error");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 len=sizeof(cin);struct sockaddr_in sock[1024];char ok[50];int newfd=-1;int maxfd=4;struct pollfd fds[1024];fds[0].fd=0;fds[0].events=POLLIN;fds[1].fd=sfd;fds[1].events=POLLIN;int count=2;puts("准备就绪");while(1){if(poll(fds,count,-1)==-1){perror("poll error");return -1;}for(int i=0;i<count;i++){ if(fds[i].revents!=POLLIN){continue;}if(i==0){scanf("%s",ok);printf("终端输入%s\n",ok);if(strcmp(ok,"quit")==0)goto aa;for(int j=2;j<count;j++){send(fds[j].fd,ok,sizeof(ok),0);}}else if(i==1){if((newfd=accept(sfd,(struct sockaddr*)&cin,&len))==-1){perror("accept error");return -1;}printf("[%s-%d]:连接成功,newfd=%d\n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_port),newfd);fds[count].fd=newfd;fds[count].events=POLLIN;count++;sock[newfd]=cin;}else{char buf[128]="";int res=recv(fds[i].fd,buf,sizeof(buf),0);if(res==0){close(fds[i]);printf("[%s-%d]:退出\n",inet_ntoa(sock[fds[i].fd].sin_addr),ntohs(sock[fds[i].fd].sin_port));fds[i]=fds[count--];continue;}printf("[%s-%d]:%s\n",inet_ntoa(sock[fds[i].fd].sin_addr),ntohs(sock[fds[i].fd].sin_port),buf);strcat(buf,"sb");send(fds[i].fd,buf,sizeof(buf),0);}}}
aa:close(sfd);return 0;
}