网站首页怎么做营业执照链接,企业推广类网站,舞台灯光网站建设,商贸有限公司简介作业#xff1a;
运行1个服务器和2个客户端 实现效果#xff1a; 服务器和2个客户端互相聊天#xff0c;服务器和客户端都需要使用select模型去实现 服务器要监视2个客户端是否连接#xff0c;2个客户端是否发来消息以及服务器自己的标准输入流 客户端要监视服务器是否发来…作业
运行1个服务器和2个客户端 实现效果 服务器和2个客户端互相聊天服务器和客户端都需要使用select模型去实现 服务器要监视2个客户端是否连接2个客户端是否发来消息以及服务器自己的标准输入流 客户端要监视服务器是否发来消息以及客户端自己的标准输入流 在不开线程的情况下实现互相聊天
代码实现
服务器
#includemyhead.h
#define SER_PORT 6666 //服务器端口号
#define SER_IP 10.80.15.182 //服务器ip地址
void insert_client(int*client_addr,int *len,int client)
{client_addr[*len] client;(*len);
}int find_client(int*client_addr,int len,int client)
{for(int i0;ilen;i){if(client_addr[i] client){return i;}}return -1;
}void remove_client(int*client_addr,int *len,int client)
{int tar find_client(client_addr,*len,client);if(tar -1){return;}int i -1;for(itar;i*len;i){client_addr[i] client_addr[i1];}(*len)--;
}int main(int argc, const char *argv[])
{int flag fcntl(0,F_GETFL);flag flag | O_NONBLOCK;fcntl(0,F_SETFL,flag);fd_set readfds;FD_ZERO(readfds);int client_addr[100] {0};int len 0;//1、创建套接字int sfd socket(AF_INET, SOCK_STREAM, 0);//参数1表示ipv4的网络通信//参数2表示使用的是TCP通信方式//参数3表示默认使用一个协议if(sfd -1){perror(socket error);return -1;}printf(socket success, sfd %d\n, sfd); //3//将端口号快速重用int reuse 1;if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, reuse, sizeof(reuse))-1){perror(setsockopt error);return -1;}printf(端口号快速重用成功\n);//2、为套接字绑定ip地址和端口号//2.1 填充地址信息结构体struct sockaddr_in sin; sin.sin_family AF_INET; //通信域sin.sin_port htons(SER_PORT); //端口号sin.sin_addr.s_addr inet_addr(SER_IP); //ip地址//2.2 绑定工作if(bind(sfd, (struct sockaddr*)sin, sizeof(sin)) -1){perror(bind error);return -1;}printf(bind success\n);//3、将套接字设置成被动监听状态if(listen(sfd, 128)-1){perror(listen error);return -1;}printf(listen success\n);FD_SET(sfd,readfds);//4、阻塞等待客户端的连接请求//4.1 定义变量用于接收客户端的信息struct sockaddr_in cin; //用于接收地址信息socklen_t addrlen sizeof(cin); //用于接收长度// struct sockaddr_in Client[128];FD_SET(0,readfds);char sbuf[128] ;while(1){fd_set temp readfds;select(FD_SETSIZE,temp,0,0,0);if(FD_ISSET(sfd,temp)){int newfd accept(sfd,(struct sockaddr*)cin,addrlen);printf(有新客户端连接\n);FD_SET(newfd,readfds);insert_client(client_addr,len,newfd);}//每一个客户端套接字都要判断是否激活如果激活了调用read读取客户端发来的消息for(int i0;ilen;i){int client client_addr[i];if(FD_ISSET(client,temp)){//客户端套接字激活有两种情况一种是发来的消息一种是断开连接char buf[128] {0};int res read(client,buf,128);if(res 0){printf(有客户端断开连接\n);//客户端断开//1.从监视链表删除FD_CLR(client,readfds);//2.从客户端数组删除remove_client(client_addr,len,client);//3.关闭套接字close(client);break;}printf(客户端发来消息%s\n,buf);}}bzero(sbuf,sizeof(sbuf));fgets(sbuf,sizeof(sbuf),stdin);sbuf[strlen(sbuf) - 1] 0;if(FD_ISSET(0,temp)){for(int i0;ilen;i){int client client_addr[i];send(client,sbuf,strlen(sbuf),0);}}}//6、关闭监听close(sfd);return 0;
}客户端
#includemyhead.h#define SER_PORT 6666 //与服务器保持一致
#define SER_IP 10.80.15.182 //服务器ip地址
#define CLI_PORT 8888 //客户端端口号
#define CLI_IP 10.80.15.182 //客户端ip地址int main(int argc, const char *argv[])
{int flag fcntl(0,F_GETFL);flag flag | O_NONBLOCK;fcntl(0,F_SETFL,flag);fd_set readfds;FD_ZERO(readfds);int client_addr[100] {0};int len 0;//1、创建用于通信的套接字文件描述符int cfd socket(AF_INET, SOCK_STREAM, 0);if(cfd -1){perror(socket error);return -1;}printf(cfd %d\n, cfd); //3//2、绑定IP地址和端口号//2.1 填充地址信息结构体struct sockaddr_in cin; cin.sin_family AF_INET; //通信域cin.sin_port htons(CLI_PORT); //端口号cin.sin_addr.s_addr inet_addr(CLI_IP); //ip地址//2.2 绑定工作/*if(bind(cfd, (struct sockaddr*)cin, sizeof(cin)) -1){perror(bind error);return -1;}printf(bind success\n);*///3、连接到服务器//3.1 填充服务器地址信息结构体struct sockaddr_in sin;sin.sin_family AF_INET; //通信域sin.sin_port htons(SER_PORT); //服务器端口号sin.sin_addr.s_addr inet_addr(SER_IP); //服务器ip地址//3.2 连接服务器if(connect(cfd, (struct sockaddr*)sin, sizeof(sin)) -1){perror(connect error);return -1;}printf(连接服务器成功\n);FD_SET(cfd,readfds);FD_SET(0,readfds);//4、数据收发char buf[128] ;while(1){fd_set temp readfds; select(FD_SETSIZE,temp,0,0,0);if(FD_ISSET(cfd,temp)){char rbuf[128] ;int res recv(cfd,rbuf,sizeof(rbuf),0);if(res 0){printf(服务器已下线\n);FD_CLR(cfd,readfds);break;}printf(服务器发来消息%s\n,rbuf);}bzero(buf,sizeof(buf));fgets(buf, sizeof(buf), stdin); //从终端获取一个字符串if(strlen(buf) ! 0){buf[strlen(buf)-1] 0;}if(FD_ISSET(0,temp)){send(cfd, buf, strlen(buf),0);printf(发送成功\n);}//接受服务器发来的数据//清空容器/* bzero(buf, sizeof(buf));recv(cfd, buf, sizeof(buf), 0);printf(收到服务器消息为%s\n, buf);*/}//5、关闭套接字close(cfd);return 0;
}