服务器
#include <poll.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <myhead.h>#define IP "192.168.60.54"
#define PORT 8848
#define BACKLOG 50struct client_info{struct sockaddr_in addr;int fd;
};//定义结构体int main(int argc, const char *argv[])
{struct client_info clients[100];//定义保护客户端信息的数组//1、创建套接字int oldfd = socket(AF_INET,SOCK_STREAM,0);if(oldfd == -1){perror("socket");return -1;}//端口快速复用int n = 1;int res = setsockopt(oldfd,SOL_SOCKET,SO_REUSEADDR,&n,sizeof(n));if(res == 0){printf("端口快速复用成功\n");}//2、绑定端口号和IP地址(结构体赋值)struct sockaddr_in server = {.sin_family = AF_INET,.sin_port = htons(PORT),.sin_addr.s_addr = inet_addr(IP)};if(bind(oldfd,(struct sockaddr *)&server,sizeof(server))==-1){perror("bind");return -1;}; //3、监听if(listen(oldfd,BACKLOG) == -1){perror("listen");return -1;}//4、设置结构体数组检测事件发生struct pollfd fds[100];fds[0].fd = oldfd;fds[0].events = POLLIN;//5、接受客户端连接请求创建新的描述符用于通信struct sockaddr_in client;socklen_t client_len = sizeof(client);int newfd,count =1,i;while(1){int res = poll(fds,100,-1);if(res == -1){perror("poll");continue;}if(res == 0){printf("超时\n");continue;}if(fds[0].revents == POLLIN)//旧套接字触发事件{newfd = accept(oldfd,(struct sockaddr *)&client,&client_len);if(newfd == -1){perror("accept");return -1;}printf("%s发来连接请求\n",inet_ntoa(client.sin_addr));fds[count].fd = newfd;//客户端放入检测组中clients[count].fd = newfd;memcpy(&clients[count].addr,&client,sizeof(client));fds[count++].events = POLLIN;//触发标志放入数组中}for(i=1;i<=count;i++)//新客户端连入后接收消息{if(fds[i].fd>0 && fds[i].revents == POLLIN){char buff[1024];char broadcast_msg[1024];memset(buff,0,sizeof(buff));//清空缓冲区memset(broadcast_msg,0,sizeof(broadcast_msg));//清空缓冲区int len = recv(fds[i].fd,buff,sizeof(buff),0);if(len == 0){printf("%s用户下线\n",inet_ntoa(clients[i].addr.sin_addr));//使用保存的地址退出close(fds[i].fd);fds[i].fd = -1;//清除已断开连接clients[i].fd = -1;//清除客户端信息break;}printf("%s发来消息:%s\n",inet_ntoa(clients[i].addr.sin_addr,buff));snprintf(broadcast_msg, sizeof(broadcast_msg), "[%s]说:%s",inet_ntoa(clients[i].addr.sin_addr), buff);for(int j=1;j<=count;j++){send(fds[j].fd,broadcast_msg,sizeof(broadcast_msg),0); }}}}close(oldfd);return 0;
}
客户端
#include <myhead.h>
#define IP "192.168.60.54"
#define PORT 8848int main(int argc, const char *argv[])
{//1、创建套接字int oldfd = socket(AF_INET,SOCK_STREAM,0);if(oldfd == -1){perror("socket");return -1;}//2、连接服务器struct sockaddr_in server = {.sin_family = AF_INET,.sin_port = htons(PORT),.sin_addr.s_addr = inet_addr(IP)};if(connect(oldfd,(struct sockaddr *)&server,sizeof(server)) == -1){perror("connect");return -1;}//3、数据收发char buff[1024];while(1){fgets(buff,sizeof(buff),stdin);buff[strlen(buff)-1] = '\0';send(oldfd,buff,sizeof(buff),0);int len = recv(oldfd,buff,sizeof(buff),0);if(len == 0){printf("服务器意外退出\n");break;}printf("接收服务器消息:%s\n",buff);}close(oldfd);return 0;
}