cs
复制代码
2
3 #define BUFSIZE 1024
4 #define login_msg_len 20
5
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_l
82 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 }
~
~
cs
复制代码
#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;
}