linux上的一个简单的多人聊天室

时间:2022-10-08 10:15:43

[文件] i.h ~ 5KB    下载(938)

001 /*
002  *i.h is a used for creating a library
003  *for server client
004  *Mar 18 2010   
005  *
006  */
007 #ifndef _I_H
008   
009 #define _I_H
010   
011 #include <math.h>
012 #include <stdio.h>
013 #include <sys/socket.h>
014 #include <arpa/inet.h>
015 #include <netinet/in.h>
016 #include <unistd.h>
017 #include <sys/types.h>
018 #include <sys/stat.h>
019 #include <fcntl.h>
020 #include <stdlib.h>
021 #include <errno.h>
022 #include <string.h>
023 #include <inttypes.h>
024 #include <time.h>
025 #include <sys/ioctl.h> 
026 #include <net/if.h>
027 #include <signal.h>
028 #include <ncurses.h>
029 #include <math.h>
030   
031 #define SEVR_IP     "127.0.0.1"
032 #define SEVR_PORT   8081
033 #define CNTNT_LEN   150
034 #define MSG_LEN     sizeof(struct msg)
035 #define ADDR_LEN    sizeof(struct sockaddr)
036 #define USR_LEN     sizeof(struct user)
037 #define PRT_LEN     8
038 #define HSTR_LEN    sizeof(struct chat_history)
039   
040 /* declare Global variables */
041 int mainfd;/* used as chat histroy file handle*/
042 int sockfd;/* used as socket local handle */
043 int count;
044 struct sockaddr_in server;
045   
046 /* msg is used for communicating message */
047 struct msg
048 {
049     int flag; /* flag meaning:1,ordinary; 2,log msg; 3,reg msg, other,file*/
050     int id_from;
051     int id_to;
052     char content[CNTNT_LEN];
053     char append[10]; 
054 };
055   
056 /* user is used information list */
057 struct user
058 {
059     int id;
060     char name[10];
061     char password[10];
062     char *p_chatlog;
063     struct sockaddr user_addr;  
064 };
065 /* chat_history used for reading chat history */
066 struct chat_history
067 {
068     char content[CNTNT_LEN];
069     char time[25];
070     int to;
071     int from;
072     int count;
073 };
074   
075 /* i_functions below is funtions needed by both client and sever */
076 extern int i_saveto_chat(struct msg *pmsg);
077   
078 int i_clean_stdin ()
079 {
080     while ('\n' == getchar())
081     {
082         continue;
083     }
084   
085     return(0);
086 }
087   
088 int i_print(char *pmsg, int size)
089 {
090     int i = 1;
091   
092     for (i; i<= size; i++)
093     {
094         if (*pmsg != '\n')
095         {
096             printf("%c", *pmsg);
097             pmsg ++;
098         }
099         else 
100         {
101             return(0);
102         }
103     }
104   
105     return(0);
106 }
107 int i_input(char *p_input)
108 {
109     char c = '\0';
110     int i;  
111   
112     for (i = 0; i < CNTNT_LEN; i++)
113     {
114         p_input[i] = getchar();
115         if (p_input[i] =='\n')
116         {
117             return(0);      
118         }       
119     }
120   
121     printf("you have input long enough!\n");
122     return(0);
123 }
124 int i_socket(int domain, int type, int protocol)
125 {
126     int fd; 
127   
128     if ((fd = socket(domain, type, protocol)) == -1)
129     {
130         perror("creat socket error:");
131         exit(1);
132     }
133       
134     return(fd); 
135 }
136   
137 int i_bind(int fd, const struct sockaddr *addr, int namelen)
138 {
139     if (-1 == bind(fd, addr, namelen))
140     {
141         perror("i_bind error:");
142         exit(1);
143     }
144       
145     return (0);
146 }
147   
148 int i_recvfrom(int fd, void *buf, size_t len, int flags, 
149         struct sockaddr *addr, int *size)
150 {   
151     if (-1 == recvfrom(fd, buf, len, flags, addr, size))
152     {
153         perror("i_recvfrom error:");
154         exit(1);    
155     }
156       
157     return(0);
158 }
159   
160 int i_sendto(int fd, void *buf, size_t len, int flags,
161         struct sockaddr *addr, int size)
162 {
163     if (-1 == sendto(fd, buf, len, flags, addr, size))
164     {
165         perror("i_sendto error");
166         exit(1);    
167     }
168       
169     return (0);
170 }
171   
172 int i_open(const char *pathname, int flags)
173 {
174     int fd;
175     if ((fd = open(pathname, flags)) == -1)
176     {
177         perror("open_failed");
178         exit(1);
179     }
180       
181     return (fd);
182 }
183 int i_read(int fd, void *msg, int len)
184 {
185     if(-1 == read(fd, msg, len))
186     {
187         perror("i_read error");
188         exit(1);
189     }
190     return(0);
191 }
192 int i_write(int fd, void *msg, int len)
193 {
194     if (-1 == write(fd, msg, len))
195     {
196         perror("i_write error");
197         exit(0);
198     }
199     return(0);
200 }
201   
202 /* init a socket,file and server addr */
203 int i_init()
204 {
205     mainfd = i_open("./chat_log", O_RDWR|O_CREAT);
206     sockfd = i_socket(AF_INET, SOCK_DGRAM, 0);
207   
208     /* initialize server address */
209     bzero(&server, sizeof(server));
210     server.sin_family = AF_INET;
211     inet_pton(AF_INET, "127.0.0.1", &server.sin_addr);
212     server.sin_port = htons(SEVR_PORT);
213   
214     perror("init");
215       
216     return (0);
217 }
218   
219 char *i_get_time()
220 {
221     time_t time_now;
222     time(&time_now);
223   
224     return(ctime(&time_now));
225 }
226 int i_lseek(int fd, off_t size, int position)
227 {
228     if (-1 == lseek(fd, size, position))
229     {
230         perror("seek error");
231         exit(1);
232     }
233     return(0);
234 }
235 int i_saveto_chat(struct msg *pmsg)
236 {   
237     struct chat_history hstr;
238   
239   
240     bzero(&hstr, HSTR_LEN);
241     count = count + 1;
242     hstr.count =count;
243     hstr.from = pmsg->id_from;
244     hstr.to = pmsg->id_to;
245     strncpy(hstr.content, pmsg->content, CNTNT_LEN);
246     strncpy(hstr.time, i_get_time(), 25);
247   
248     i_lseek(mainfd, 0, SEEK_END);
249   
250     i_write(mainfd, &hstr, HSTR_LEN);
251   
252     return(0);
253 }
254   
255 int i_print_history(int len, int i)
256 {
257     struct chat_history chat_reader;
258     int j;
259     int position;
260       
261     bzero(&chat_reader, HSTR_LEN);
262     if (i != 0)
263     {
264         position = len*i*HSTR_LEN;
265         i_lseek(mainfd, position, SEEK_END);
266     }
267     else
268     {
269         position = len*i*HSTR_LEN;
270   
271         i_lseek(mainfd, HSTR_LEN, SEEK_SET);
272     }
273           
274     for (j = 1; j <= len; j++)
275     {
276           
277         i_read(mainfd, &chat_reader, HSTR_LEN);
278         printf("\n#item%d:id%dto id%d \n", j,
279             chat_reader.from, chat_reader.to);
280         i_print(chat_reader.content, CNTNT_LEN);
281         printf("\n  Time:%s\n", chat_reader.time);
282     }
283   
284     return(0);
285 }
286   
287 #endif

[文件] server.c ~ 6KB    下载(635)

001 /*
002  *title:server.c
003  *content:server part
004  *start time: Mar.25.2011
005  *end time:  Apr.8 2011
006  */
007   
008 #include "i.h"
009   
010 int user_list_fd;
011   
012 /* start:initialization */
013 int init()
014 {
015     i_init();
016   
017     user_list_fd = i_open("./user_list", O_RDWR|O_CREAT);
018   
019     struct user usr;
020     /* init the user list file's fist user to 0*/
021     memset((struct user*)&usr, '\0', sizeof(struct user));
022     i_lseek(user_list_fd, 0, SEEK_SET);
023     i_write(user_list_fd, (char*)&usr, USR_LEN);
024   
025     /* bind the struct sockaddr_in server to the sockfd */
026     i_bind(sockfd, (struct sockaddr*)&server, ADDR_LEN);    
027   
028     struct chat_history apple;  
029   
030     bzero(&apple, HSTR_LEN);
031     i_lseek(mainfd, 0, SEEK_SET);
032     i_write(mainfd, &apple, HSTR_LEN);
033     i_lseek(mainfd, -HSTR_LEN, SEEK_END);
034     i_read(mainfd, &apple, HSTR_LEN);
035     count = apple.count;
036   
037     return(0);
038 }
039 /* end:initialization */
040   
041 /* start:message control */
042 int send_msg(struct msg *msg_recv, struct sockaddr *addr)
043 {
044     int i;
045     struct user usr;
046   
047     /* a common message come */ 
048     printf("a ordinar message come !\n");
049       
050     i = msg_recv->id_to;
051     i_lseek(user_list_fd, i*USR_LEN, SEEK_SET);
052     i_read(user_list_fd, &usr, USR_LEN);
053     strncpy(msg_recv->append, usr.name, 10);
054   
055     i_sendto(sockfd, msg_recv, MSG_LEN, 0,
056         &(usr.user_addr), ADDR_LEN);
057       
058     printf("id%d send a message to id%d sucess!\n", msg_recv->id_from, msg_recv->id_to);
059   
060     return(0);
061 }
062 int check_login(struct msg *msg_recv, struct sockaddr *addr)
063 {
064     int i = msg_recv->id_from;;
065     struct user usr;
066   
067     /* a login requet */
068     printf("a login request come!\n");
069       
070     /* get the id's information */
071     i_lseek(user_list_fd, i*USR_LEN, SEEK_SET);
072     i_read(user_list_fd, &usr, USR_LEN);
073   
074     int n;
075     n = strcmp(usr.password, msg_recv->content);
076     /* 如果验证成功,则发送成功信息 */
077     if (n == 0)
078     {
079         /* save user new address */
080         i_lseek(user_list_fd, -USR_LEN, SEEK_CUR);
081         usr.user_addr = *addr;
082         i_write(user_list_fd, &usr, USR_LEN);
083         /* tell user pass */
084         i_sendto(sockfd, (struct msg*)msg_recv, sizeof(struct msg), 0,
085             &(usr.user_addr), ADDR_LEN);
086           
087     }
088     else
089     {
090         /* 出错的话的respond */
091         if (0 != n)
092         {
093             printf("id %d login error.\n", i);
094             bzero(msg_recv->content, CNTNT_LEN);         
095             msg_recv->flag = -1;
096             i_sendto(sockfd, (struct msg*)msg_recv, sizeof(struct msg), 0,
097                 &(usr.user_addr), ADDR_LEN);
098           
099         }
100         return(1);
101     }
102     printf("Id %d login sucess!\n", i); 
103       
104     return(0);
105 }
106 int reg_user(struct msg *msg_recv, struct sockaddr *addr)
107 {
108     struct user usr;
109       
110     printf("a regit requet come:\n");
111   
112     /* find the last user and hava the please to add a new user */
113     int n;
114     i_lseek(user_list_fd, -USR_LEN, SEEK_END);
115     i_read(user_list_fd, &usr, USR_LEN);
116     /* 把新用户的信息赋值到usr然后填入到user list file中 */
117     const char *name;
118     const char *password;
119   
120     name = &(msg_recv->content[0]);
121     password = &(msg_recv->content[10]);
122     strcpy((usr.name), name);
123     strcpy(usr.password, password);
124     memcpy(&(usr.user_addr),addr, ADDR_LEN);
125   
126     usr.id = (usr.id + 1);
127     i_lseek(user_list_fd, 0, SEEK_END);
128     i_write(user_list_fd, &usr, USR_LEN);
129   
130     msg_recv->id_from = usr.id;
131     /* regist to the user list then tell the user reg success */
132     i_sendto(sockfd, (struct msg*)msg_recv, sizeof(struct msg), 0,
133         addr, ADDR_LEN); 
134   
135     printf("Id %d regist sucess!\n", usr.id);
136   
137     return(0);
138       
139 }
140 int msg_cntl()
141 {
142     struct msg msg_recv;
143     struct sockaddr addr_recv;
144   
145     printf("begin listen input...\n");
146     int size = ADDR_LEN;
147   
148     for (;;)
149     {
150         bzero(&msg_recv, MSG_LEN);
151         i_recvfrom(sockfd, &msg_recv, sizeof(struct msg), 0,
152             &addr_recv, &size);
153         printf("message received...\n");
154   
155         i_saveto_chat(&msg_recv);
156   
157         switch (msg_recv.flag)
158         {
159             case 1 :
160                 send_msg(&msg_recv,(struct sockaddr*)&addr_recv);/* send ordinary chat */
161                 break;
162             case 2 :
163                 check_login(&msg_recv, (struct sockaddr*)&addr_recv);
164                 break;          
165             case 3 :
166                 reg_user(&msg_recv, (struct sockaddr*)&addr_recv);
167                 break;
168             default :
169                 break;
170         }
171     }
172     return(0);
173 }
174 /* end:message control*/
175 /* start:exit_sys()*/
176 int exit_sys()
177 {
178     close(sockfd);
179     close(mainfd);
180     close(user_list_fd);
181     printf("exit system");
182     kill(0, SIGABRT);
183   
184     exit(0);
185 }
186 /* end:exit_sys()*/
187   
188 /* start:chat_history*/
189 int get_page_size()
190 {
191     struct chat_history page_size_reader;
192       
193     i_lseek(mainfd, -HSTR_LEN, SEEK_END);
194     i_read(mainfd, &page_size_reader, HSTR_LEN);
195   
196     return(page_size_reader.count);
197 }
198   
199 int read_chat_history()
200 {
201     printf("****char*history***");
202     printf("(n-nextpage; p-prepage; q-quit)\n");
203   
204     int page_num;/* */
205     int remains;
206     int berry = get_page_size();
207   
208   
209     page_num = berry / 8;
210     remains = berry % 8;
211   
212     if (remains != 0)
213         page_num ++;
214     else
215         page_num = page_num;
216           
217     printf("there are %d page total %d items"
218         page_num, berry);
219   
220     int i = -1;
221   
222     while (1)
223     {   
224         char flag;  
225   
226         if ((berry + i*8) >= 0)
227         {
228             printf("(%d~%d)\n", (berry + i*8), (berry + (i+1)*8));
229   
230             i_print_history(PRT_LEN, i);
231   
232             printf("@@@\n");
233             while ('\n' == (flag = getchar()))
234             {
235             }
236   
237             switch (flag)
238             {
239                 case 'p' :
240                     i--;
241                     break;
242                 case 'n' :
243                     i++;
244                     break;
245                 case 'q' :
246                     return(0);
247                 default  :
248                     break;
249             }   
250             if (i >= 0)
251             {
252                 printf("have at the end!\n");
253                 printf("return to menu!\n");
254             }       
255         }
256         else 
257         {
258             printf("(1~%d)\n", remains);            
259           
260             i_print_history(remains, 0);
261               
262             printf("#########over##############\n");
263   
264             return(0);
265         }   
266     }
267           
268     return(0);
269 }
270 /* end:chat_history*/
271 /* start:menu*/
272 int menu()
273 {
274     sleep(1);
275   
276     printf("----------help----menu---------\n");
277     printf("\t r--report to user\n");
278     printf("\t c--chat history\n");
279     printf("\t h--help menu\n");
280     printf("\t e--exit the system\n");
281     printf("----------help_menu---------\n");
282   
283     int command = 0;
284   
285     printf("input command>");
286     command = getchar();
287     switch(command)
288     {
289   
290         case 'c':
291             read_chat_history();
292             break;
293         case 'e':
294             exit_sys();
295             break;
296         case 'r':
297             //report();
298             //break;
299         default :
300             menu();
301             break;
302     }
303     getchar();
304       
305     return(0);
306 }
307 /* end:menu*/
308 int main()
309 {
310     init();
311     pid_t pid;
312     switch (pid = fork())
313     {
314         case -1 :
315             perror("fork error\n");
316             exit(1);
317             break;
318         case 0 :
319             msg_cntl();
320             break;
321         default :
322             menu();
323             break;
324     }
325   
326     return(0);
327 }

[文件] client.c ~ 8KB    下载(643)

001 /*
002  *title: client.c
003  *start_time: Mar.18 2011
004  *end_time:  Apr.8 2011
005  */
006   
007 #include "i.h"
008   
009 #define START_PORT 8089
010   
011 struct sockaddr_in my_addr;
012 int my_id;
013   
014 int my_log();/* declare funtion*/
015   
016 /* */
017 int i_send_msg()
018 {       
019     int id;
020     struct msg the_msg;
021     char end = '@';
022   
023     printf("input recver id:");
024     scanf("%d", &id);
025     getchar();
026     printf("\ninput content:");
027     i_input(the_msg.content);   
028   
029     char flag = 'y';
030           
031     if (1)
032     {
033         the_msg.flag = 1;
034         the_msg.id_from = my_id;
035         the_msg.id_to = id;
036           
037         i_sendto(sockfd, &the_msg, sizeof(struct msg), 0,
038             (struct sockaddr*)&server, sizeof(struct sockaddr));
039           
040         i_saveto_chat(&the_msg); /* save to history */
041   
042         printf("send to id:%d success.\n", my_id);
043         return(0);
044     }
045     else
046         return(1);
047   
048     return(0);
049 }
050   
051 int reply()
052 {
053     return(0);
054 }
055 int send_file()
056 {
057     return(0);
058 }
059 /**/
060 /* start:initialize */
061 int init()
062 {   
063     struct ifreq req;
064     struct sockaddr_in *host;
065     int port;
066   
067     i_init();
068     /* init user addr */
069     bzero(&my_addr, sizeof(struct sockaddr));
070     my_addr.sin_family = AF_INET;
071     strcpy(req.ifr_name, "lo");
072     if ( ioctl(sockfd, SIOCGIFADDR, &req) < 0 ) /* get local ip address */
073     {
074         perror("get local ip error");
075         exit(1);
076         
077   
078     host = (struct sockaddr_in*)&(req.ifr_addr);
079     printf("ip: %s\n", inet_ntoa(host->sin_addr));
080   
081     memcpy(&my_addr, (struct sockaddr_in*)&(req.ifr_addr),
082          sizeof(struct sockaddr_in));
083   
084     port = START_PORT;
085   
086     do 
087     {
088         port++;
089         my_addr.sin_port = htons(port);
090         bind(sockfd, (struct sockaddr*)&my_addr,
091              sizeof(struct sockaddr));      
092     
093     while (errno == EADDRINUSE);
094   
095     struct chat_history apple;  
096       
097     memset(&apple, 'b', HSTR_LEN);
098     i_lseek(mainfd, 0, SEEK_SET);
099     apple.count = 0;
100     i_write(mainfd, &apple, HSTR_LEN);
101     i_lseek(mainfd, -HSTR_LEN, SEEK_END);
102     i_read(mainfd, &apple, HSTR_LEN);
103     count = apple.count;
104   
105     
106     printf("port:%d\n", port);  
107     printf("init successful!!!\n"); 
108   
109     return(0);
110   
111 }
112 /* end:initialize */
113 /* start:chat_history*/
114 int get_page_size()
115 {
116     struct chat_history page_size_reader;
117       
118     i_lseek(mainfd, -HSTR_LEN, SEEK_END);
119     i_read(mainfd, &page_size_reader, HSTR_LEN);
120   
121     return(page_size_reader.count);
122 }
123   
124 int read_chat_history()
125 {
126     printf("****char*history***");
127     printf("(n-nextpage; p-prepage; q-quit)\n");
128   
129     int page_num;/* */
130     int remains;
131     int berry = get_page_size();
132   
133   
134     page_num = berry / 8;
135     remains = berry % 8;
136   
137     if (remains != 0)
138         page_num ++;
139     else
140         page_num = page_num;
141           
142     printf("there are %d page total %d items"
143         page_num, berry);
144   
145     int i = -1;
146   
147     while (1)
148     {   
149         char flag;  
150   
151         if ((berry + i*8) >= 0)
152         {
153             printf("(%d~%d)\n", (berry + i*8), (berry + (i+1)*8));
154   
155             i_print_history(PRT_LEN, i);
156   
157             printf("@@@\n");
158             while ('\n' == (flag = getchar()))
159             {
160             }
161   
162             switch (flag)
163             {
164                 case 'p' :
165                     i--;
166                     break;
167                 case 'n' :
168                     i++;
169                     break;
170                 case 'q' :
171                     return(0);
172                 default  :
173                     break;
174             }   
175             if (i >= 0)
176             {
177                 printf("have at the end!\n");
178                 printf("return to menu!\n");
179             }       
180         }
181         else 
182         {
183             printf("(1~%d)\n", remains);            
184           
185             i_print_history(remains, 0);
186               
187             printf("#########over##############\n");
188   
189             return(0);
190         }   
191     }
192           
193     return(0);
194 }
195 /* end:chat_history*/
196 /* start:exit_sys*/
197 void exit_sys()
198 {
199     close(sockfd);
200     close(mainfd);
201     kill(0, SIGABRT);
202   
203     exit(0);
204 }
205 /* end:exit_sys*/
206   
207 /* start:menu*/
208 int print_menu()
209 {
210     printf("\n--------------help--menu----------------\n");
211     printf("\t h--help munu\n");
212     printf("\t s--send message\n");
213     printf("\t r--reply to\n");
214     printf("\t c--chat history\n");
215     printf("\t f--send files\n");
216     printf("\t e--exit the system\n");
217     printf("----------------help--menu----------------\n");
218 }
219 int get_input(char *command)
220 {   
221     printf(">");
222     scanf("%c", command);
223   
224     return(1);
225 }
226 int menu()
227 {
228     /* to avoid the output at mixed with the sub process */
229     sleep(1);
230   
231     print_menu();
232       
233     char command;
234   
235     while (1 == get_input(&command))
236     {   
237         switch(command)
238         {
239             case 'h':
240                 print_menu();
241                 break;      
242             case 's':
243                 i_send_msg();
244                 break;
245             case 'r':
246                 reply();
247                 break;
248             case 'f':
249                 send_file();
250                 break;
251             case 'c':
252                 read_chat_history();
253                 break;
254             case 'e':
255                 exit_sys();
256                 break;
257             default :
258                 printf(">");
259                 break;
260         }
261     }
262     return(0);
263 }
264 /* end:menu*/
265 /* start:message contol :send_msg and recv_msg */
266 int ordnary_msg_recv(struct msg *pmsg)
267 {
268     char time_info[25];
269     char end_symble;
270     end_symble = '&';
271   
272     /* handle the msg */
273     printf("Message:from %s(id%d) to U:\n", pmsg->append, pmsg->id_from);
274     i_print(pmsg->content, MSG_LEN);
275     printf("\n\t%s", i_get_time());
276   
277     return(0);
278 }
279 int file_msg_recv(struct msg *pmsg)
280 {
281 }
282 int handle_msg(struct msg *pmsg)
283 {   
284     if (pmsg->flag == 1)
285     {
286         ordnary_msg_recv(pmsg);
287         return(0);
288     }
289     else if (pmsg->flag >= 4)
290     {
291         file_msg_recv(pmsg);
292         return(0);
293     }   
294     return(0);
295 }
296 int listen_msg()
297 {
298     struct msg msg_recv;
299     struct sockaddr addr_recv;
300     int len = ADDR_LEN;
301   
302     printf("begin listen...\n");
303   
304     for ( ; ; )
305     {   
306         i_recvfrom(sockfd, &msg_recv, MSG_LEN, 0, 
307              &addr_recv, &len);
308   
309         i_saveto_chat(&msg_recv); /* save to history */
310           
311          ordnary_msg_recv(&msg_recv);
312     }
313 }
314   
315 /* end:message contol*/
316   
317 /* start:log process :login and regist */
318 int login()
319 {
320     /* input id:*/
321     printf("*****login>>\n");
322     printf("id:");
323     scanf("%d", &my_id);
324     /* input password*/
325     char password[15];
326     printf("\npassword(*less 15 char):");
327     scanf("%s", password);
328     getchar();
329       
330     /* send login information */
331     struct msg log_msg;
332   
333     bzero(&log_msg, MSG_LEN);
334     log_msg.flag = 2;
335     log_msg.id_from = my_id;
336     log_msg.id_to = 0;
337     strncpy(log_msg.content, password, 15);
338   
339     i_saveto_chat(&log_msg); /* save to history */
340       
341     i_sendto(sockfd, (struct msg*)&log_msg, MSG_LEN, 0, 
342         (struct sockaddr*)&server, sizeof(struct sockaddr));
343 //printf("log_msg : %d\n", log_msg.id_from);
344 //printf("password: %s\n", log_msg.content);
345     /* after input msg ,wait for server respond*/
346     struct sockaddr in_addr;
347     int len = ADDR_LEN;
348     i_recvfrom(sockfd, (struct msg*)&log_msg, MSG_LEN,0,
349         &in_addr, &len);
350     if (2 == log_msg.flag)
351     {
352         printf("login success\n");
353         return(0);
354     }   
355     else
356     {
357         printf("login error:%s\n", log_msg.content);
358         printf("please relog..\n");
359         menu();
360     }
361       
362     return (0);
363 }
364 int regist()
365 {
366     printf("*****regist>>\n");
367     /* input chat name */
368     char name[10];
369   
370     bzero(name, 10);
371     printf("input your chat name(less 8 char):");
372     scanf("%s", name);
373   
374     //name[9] = ';';         /* add a ; symbol in the end of name */
375     /* input password */
376     char password[15];
377   
378     bzero(password, 15);
379     printf("\ninput your password(less 14 char):");
380     scanf("%s", password);
381   
382     /* send regist information*/
383     struct msg reg_msg;
384   
385     bzero(&reg_msg, MSG_LEN);
386     reg_msg.flag = 3;
387     reg_msg.id_from = 0;
388     reg_msg.id_to = 0;
389     bzero(reg_msg.content, CNTNT_LEN);
390     strncpy(reg_msg.content, name, 10);
391     strncpy(&(reg_msg.content[10]), password, 15);
392     reg_msg.content[25] = '\n';
393   
394     i_saveto_chat(&reg_msg); /* save to history */
395   
396     /* send regist informatin to server */
397     i_sendto(sockfd, (struct msg*)&reg_msg, sizeof(struct msg), 0, 
398         (struct sockaddr*)&server, ADDR_LEN);
399     /* after input msg ,wait for server respond*/
400     printf("wating for server reply...\n");
401   
402     struct sockaddr in_addr;
403     struct msg msg_back;
404     int len = ADDR_LEN;
405       
406     bzero(&in_addr, ADDR_LEN);
407     bzero(&msg_back, MSG_LEN);
408     i_recvfrom(sockfd,(struct msg*)&msg_back, MSG_LEN,0,
409         &in_addr, &len);
410   
411     /* check whether pass */
412     if (3 != msg_back.flag)
413     {
414         printf("error: %s \n", msg_back.content);
415         exit(1);
416     }
417     else
418         my_id = msg_back.id_to;
419         printf("congratulate! you have regist" 
420             "id %s(id %d) success\n", msg_back.content, msg_back.id_to);
421   
422         login();
423   
424     return(0);  
425 }
426   
427 int my_log()
428 {
429     /* choose login or regist*/
430     char flag;
431     printf("are you want login or regist(l/r)\n");
432     scanf("%c", &flag);
433     getchar();
434     switch (flag){
435         case 'l' :
436             login();
437             break;
438         case 'r' :
439             regist();
440             break;
441         default :
442             printf("error input\n");
443             my_log();
444             break;
445     }
446     return (0);
447 }
448 /* end:log */
449   
450 int main()
451 {
452     init();
453     printf("\n************welcome!************\n");
454     my_log();
455   
456     pid_t pid;
457   
458     switch (pid = fork())
459     {
460         case -1 :
461             perror("fork error!\n");
462             exit(1);
463             break;
464         case 0 :
465             listen_msg();
466             break;
467         default :
468             menu();
469             break;
470     }
471 }