当前位置: 首页 > news >正文

5.26作业

服务器

  2 3 #define BUFSIZE 10244 #define login_msg_len 205 6 typedef struct Node{7     char name[login_msg_len];8     struct sockaddr_in addr;9     struct Node *next;10 }Node;11 12 typedef struct Msgtype{13     char type;14     char username[login_msg_len];15     char content[BUFSIZE];16 }Msgtype;17 18 Node *create_node(in_port_t SER_PORT,const char * SER_IP_STR);19 Node *add_node(char *name,struct sockaddr_in addr);20 int print_msg(Msgtype *msg);21 void broadcast(int sfd,Node *head,Msgtype *msg);22 int is_exist(Node *head,Msgtype *msg);23 int is_empty(Node *head);24 void insert_node(Node *head,char *name,struct sockaddr_in addr);25 void delete_node(Node *head,char *name);26 void broadcast_system(int sfd,Node *head,char *input_buf);27 28 int main(int argc, char const *argv[])29 {30     if(3>argc){31         printf("输入格式不对,请按照以下格式输入:./server ip port\n");32         exit(1);33     }34     const char *SER_IP_STR=argv[1];35     in_port_t SER_PORT=atoi(argv[2]);36 37     int sfd=-1;38     if((sfd=socket(AF_INET,SOCK_DGRAM,0))<0){39         perror("socket");40         exit(1);41     }42 43     struct sockaddr_in addr;44     memset(&addr,0,sizeof(addr));45     addr.sin_family=AF_INET;46     addr.sin_port=htons(SER_PORT);47     if(inet_aton(SER_IP_STR,&addr.sin_addr)==0){48         perror("inet_aton");49         exit(1);50     }51 52     if(bind(sfd,(struct sockaddr*)&addr,sizeof(addr))<0){53         perror("bind");54         exit(1);55     }56     printf("bind success\n");57     Node *head=create_node(SER_PORT,SER_IP_STR);58 59     struct pollfd pfd[2];60     pfd[0].fd = sfd;61     pfd[0].events = POLLIN;62     pfd[1].fd = 0;63     pfd[1].events = POLLIN;64 65     struct sockaddr_in client_addr;66     socklen_t client_addr_len=sizeof(client_addr);67 68     Msgtype client_msg;69     memset(&client_msg,0,sizeof(client_msg));70 71     while(1){72         int ret=poll(pfd,2,-1);73         if(ret<0){74             perror("poll");75             exit(1);76         }else if (ret==0){77             printf("poll timeout\n");78             continue;79         }80         if(pfd[0].revents==POLLIN){81             int recv_len=recvfrom(sfd,&client_msg,sizeof(client_msg),0,(struct sockaddr*)&client_addr,&client_addr_l82             if(recv_len<0){83                 perror("recvfrom");84                 exit(1);85             }86             if(print_msg(&client_msg)==1){87                 if(is_exist(head,&client_msg)){88                     client_msg.type='E';89                     sendto(sfd,&client_msg,sizeof(client_msg),0,(struct sockaddr*)&client_addr,sizeof(client_addr));90                     continue;91                 }else{92                     insert_node(head,client_msg.username,client_addr);93                     client_msg.type='L';94                    strcpy(client_msg.content,"进入聊天室");95                     broadcast(sfd,head,&client_msg);96                 }97             }else if (print_msg(&client_msg)==2){98                 printf("%s发送消息\n",client_msg.username);99                 broadcast(sfd,head,&client_msg);
100             }else if (print_msg(&client_msg)==3){
101                 delete_node(head,client_msg.username);
102                 client_msg.type='Q';
103                 strcpy(client_msg.content,"退出聊天室");
104                 broadcast(sfd,head,&client_msg);
105             }else{
106                 char *msg="消息类型错误";
107                 for(int i=0;i<sizeof(msg);i++){
108                     client_msg.content[i]=msg[i];
109                 }
110                 sendto(sfd,&client_msg,sizeof(client_msg),0,(struct sockaddr*)&client_addr,sizeof(client_msg));
111                 continue;
112             }
113         }
114         if(pfd[1].revents==POLLIN){
115             char input_buf[BUFSIZE];
116             fgets(input_buf,BUFSIZE,stdin);
117             input_buf[strlen(input_buf)-1]='\0';
118             if(is_empty(head)){
119                 printf("聊天室为空,请等待其他用户登录\n");
120                 continue;
121             }
122             broadcast_system(sfd,head,input_buf);
123         }
124     }
125     close(sfd);
126     return 0;
127 }
128 Node *create_node(in_port_t SER_PORT,const char * SER_IP_STR){
129     Node *node=(Node*)malloc(sizeof(Node));
130     if(node==NULL){
131         perror("malloc");
132         exit(1);
133     }
134     char *msg="system";
135     for(int i=0;i<sizeof(msg);i++){
136         node->name[i]=msg[i];
137     }
138     node->addr.sin_family=AF_INET;
139     node->addr.sin_port=htons(SER_PORT);
140     node->addr.sin_addr.s_addr=inet_addr(SER_IP_STR);
141     node->next=NULL;
142     return node;
143 }
144 Node *add_node(char *name,struct sockaddr_in addr){
145     Node *new_node=(Node*)malloc(sizeof(Node));
146     if(new_node==NULL){
147         perror("malloc");
148         exit(1);
149     }
150     strcpy(new_node->name,name);
151     new_node->addr=addr;
152     new_node->next=NULL;
153     return new_node;
154 }
155 int is_empty(Node *head){
156     if(head==NULL){
157         return 1;
158     }
159     return head->next==NULL?1:0;
160 }
161 void insert_node(Node *head,char *name,struct sockaddr_in addr){
162     if(head==NULL){
163         perror("head is null");
164         exit(1);
165     }
166     Node *new_node=add_node(name,addr);
167     new_node->next=head->next;
168     head->next=new_node;
169     printf("%s进入聊天室\n",name);
170 }
171 int print_msg(Msgtype *msg){
172     switch(msg->type){
173         case 'L':
174             return 1;
175         case 'C':
176             return 2;
177         case 'Q':
178             return 3;
179         default:
180             return 0;
181     }
182 }
183 int is_exist(Node *head,Msgtype *msg){
184     if(head==NULL){
185         perror("head is null");
186         exit(1);
187     }
188     if(is_empty(head)){
189         return 0;
190     }
191     Node *p=head->next;
192     while(p!=NULL){
193         if(strcmp(p->name,msg->username)==0){
194             return 1;
195         }
196         p=p->next;
197     }
198     return 0;
199 }
200 void broadcast(int sfd,Node *head,Msgtype *msg){
201     if(head==NULL){
202         perror("head is null");
203         exit(1);
204     }
205     if(is_empty(head)){
206         printf("聊天室为空\n");
207         return;
208     }
209     Node *p=head->next;
210     while(p!=NULL){
211         if(strcmp(p->name,msg->username)!=0){
212             sendto(sfd,msg,sizeof(Msgtype),0,(struct sockaddr*)&p->addr,sizeof(p->addr));
213         }
214         p=p->next;
215 
216     }
217 }
218 void delete_node(Node *head,char *name){
219     if(head==NULL){
220         perror("head is null");
221         exit(1);
222     }
223     if(is_empty(head)){
224         printf("聊天室为空\n");
225         return;
226     }
227     printf("%s退出聊天室\n",name);
228     Node *p=head->next;
229     Node *pre=head;
230     while(p!=NULL){
231         if(strcmp(p->name,name)==0){
232             pre->next=p->next;
233             free(p);
234             return;
235         }
236         pre=p;
237         p=p->next;
238     }
239 
240 }
241 void broadcast_system(int sfd,Node *head,char *content){
242     if(head==NULL){
243         perror("head is null");
244         exit(1);
245     }
246     if(is_empty(head)){
247         printf("聊天室为空\n");
248         return;
249     }
250     Msgtype msg;
251     msg.type='C';
252     strcpy(msg.username,"system");
253     strcpy(msg.content,content);
254     Node *p=head->next;
255     while(p!=NULL){
256         sendto(sfd,&msg,sizeof(Msgtype),0,(struct sockaddr*)&p->addr,sizeof(p->addr));
257         p=p->next;
258     }
259     printf("system发送消息:%s\n",content);
260 }
~                                                                                                                       
~                                                                                                                       

客户端

 #include <header.h>#define BUFSIZE 1024#define login_msg_len 20 typedef struct Msgtype{char type;char username[login_msg_len];char content[BUFSIZE];}Msgtype;int main(int argc, char const *argv[]){if(3>argc){                                                                                                                                            printf("输入格式不对,请按照以下格式输入:./server ip port\n");}const char *SER_IP_STR=argv[1];int SER_PORT=atoi(argv[2]);int sfd=-1;if((sfd=socket(AF_INET,SOCK_DGRAM,0))<0){perror("socket");exit(1);}struct sockaddr_in server_addr;memset(&server_addr,0,sizeof(server_addr));server_addr.sin_family=AF_INET;server_addr.sin_port=htons(SER_PORT);if(inet_aton(SER_IP_STR,&server_addr.sin_addr)==0){perror("inet_aton");exit(1);}socklen_t addr_len=sizeof(server_addr);Msgtype recv_msg;memset(&recv_msg,0,sizeof(recv_msg));Msgtype send_msg;memset(&send_msg,0,sizeof(send_msg));Msgtype login_msg;while (1){memset(&login_msg,0,sizeof(login_msg));login_msg.type='L';printf("请输入用户名:");fgets(login_msg.username, login_msg_len, stdin);login_msg.username[strcspn(login_msg.username, "\n")] = '\0'; if (sendto(sfd, &login_msg, sizeof(login_msg), 0, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0){perror("sendto");exit(1);}struct pollfd pfd[2];pfd[0].fd = sfd;        pfd[0].events = POLLIN; pfd[1].fd = 0;         pfd[1].events = POLLIN; while(1){int ret=poll(pfd,2,-1);if(ret<0){perror("poll");exit(1);}else if (ret==0){printf("poll timeout\n");continue;}if(pfd[0].revents==POLLIN){int len=recvfrom(sfd, &recv_msg, sizeof(recv_msg), 0, (struct sockaddr *)&server_addr, &addr_len);if(len<0){perror("recvfrom");exit(1);}if(recv_msg.type=='L'){printf("-----------%s加入聊天室----------\n",recv_msg.username);}else if(recv_msg.type=='C'){printf("%s:%s\n",recv_msg.username,recv_msg.content);}else if (recv_msg.type=='Q') {printf("------------%s%s---------------\n",recv_msg.username,recv_msg.content);}else{printf("%s用户名已存在或服务器故障,请重新登录\n",login_msg.username);break;}}if(pfd[1].revents==POLLIN){char input[BUFSIZE];fgets(input,BUFSIZE, stdin);input[strcspn(input, "\n")] = '\0'; if(strcmp(input,"quit")==0){send_msg.type='Q';sendto(sfd, &send_msg, sizeof(send_msg), 0, (struct sockaddr *)&server_addr, sizeof(server_addr));break;//退出循环}else{memset(&send_msg,0,sizeof(send_msg));send_msg.type='C';strncpy(send_msg.username,login_msg.username,login_msg_len);strncpy(send_msg.content,input,BUFSIZE);sendto(sfd, &send_msg, sizeof(send_msg), 0, (struct sockaddr *)&server_addr, sizeof(server_addr));}}}}close(sfd);return 0;}

http://www.lryc.cn/news/354316.html

相关文章:

  • 链接库文件体积优化工具篇:bloaty
  • 使用pyqt绘制一个爱心!
  • 关于 Transformer 的11个常见面试题
  • OS多核多线程锁记录笔记
  • nginx做TCP代理
  • python 异常处理 try
  • 月入10万+管道收益,揭秘旅游卡运营的5个阶段!
  • android_binder源码分析之_binder驱动使用服务
  • 【波点音乐看广告】
  • [SWPUCTF 2021 新生赛]pop
  • 【DevOps】Jenkins + Dockerfile自动部署Maven(SpringBoot)项目
  • 【C++】——入门基础知识超详解
  • ChatGPT技术演进简介
  • C语言 | Leetcode C语言题解之第114题二叉树展开为链表
  • Vue 子组件向父组件传值
  • 【前端笔记】Vue项目报错Error: Cannot find module ‘webpack/lib/RuleSet‘
  • edge浏览器的网页复制
  • 视频播放器-Kodi
  • Helm安装kafka3.7.0无持久化(KRaft 模式集群)
  • 【机器学习】期望最大化(EM)算法
  • 【Python】机器学习中的过采样和欠采样:处理不平衡数据集的关键技术
  • 重新思考:Netflix 的边缘负载均衡
  • 元组的创建和删除
  • CSS3用户界面
  • STL源码刨析:序列式容器之vector
  • Flutter 中的 AbsorbPointer 小部件:全面指南
  • Web开发学习总结
  • springboot相关知识集锦----1
  • App推广新境界:Xinstall助你轻松突破运营痛点,实现用户快速增长!
  • YOLOv10 论文学习