简单实现linux聊天室程序
花了很长时间用来练习掌握linux上socket的一个聊天室程序,可以实现的哦。
具体代码如下
代码一:
#ifndef_I_H #define_I_H #include<math.h> #include<stdio.h> #include<sys/socket.h> #include<arpa/inet.h> #include<netinet/in.h> #include<unistd.h> #include<sys/types.h> #include<sys/stat.h> #include<fcntl.h> #include<stdlib.h> #include<errno.h> #include<string.h> #include<inttypes.h> #include<time.h> #include<sys/ioctl.h> #include<net/if.h> #include<signal.h> #include<ncurses.h> #include<math.h> #defineSEVR_IP"127.0.0.1" #defineSEVR_PORT8081 #defineCNTNT_LEN150 #defineMSG_LENsizeof(structmsg) #defineADDR_LENsizeof(structsockaddr) #defineUSR_LENsizeof(structuser) #definePRT_LEN8 #defineHSTR_LENsizeof(structchat_history) /*declareGlobalvariables*/ intmainfd;/*usedaschathistroyfilehandle*/ intsockfd;/*usedassocketlocalhandle*/ intcount; structsockaddr_inserver; /*msgisusedforcommunicatingmessage*/ structmsg { intflag;/*flagmeaning:1,ordinary;2,logmsg;3,regmsg,other,file*/ intid_from; intid_to; charcontent[CNTNT_LEN]; charappend[10]; }; /*userisusedinformationlist*/ structuser { intid; charname[10]; charpassword[10]; char*p_chatlog; structsockaddruser_addr; }; /*chat_historyusedforreadingchathistory*/ structchat_history { charcontent[CNTNT_LEN]; chartime[25]; intto; intfrom; intcount; }; /*i_functionsbelowisfuntionsneededbybothclientandsever*/ externinti_saveto_chat(structmsg*pmsg); inti_clean_stdin() { while('\n'==getchar()) { continue; } return(0); } inti_print(char*pmsg,intsize) { inti=1; for(i;i<=size;i++) { if(*pmsg!='\n') { printf("%c",*pmsg); pmsg++; } else { return(0); } } return(0); } inti_input(char*p_input) { charc='\0'; inti; for(i=0;i<CNTNT_LEN;i++) { p_input[i]=getchar(); if(p_input[i]=='\n') { return(0); } } printf("youhaveinputlongenough!\n"); return(0); } inti_socket(intdomain,inttype,intprotocol) { intfd; if((fd=socket(domain,type,protocol))==-1) { perror("creatsocketerror:"); exit(1); } return(fd); } inti_bind(intfd,conststructsockaddr*addr,intnamelen) { if(-1==bind(fd,addr,namelen)) { perror("i_binderror:"); exit(1); } return(0); } inti_recvfrom(intfd,void*buf,size_tlen,intflags, structsockaddr*addr,int*size) { if(-1==recvfrom(fd,buf,len,flags,addr,size)) { perror("i_recvfromerror:"); exit(1); } return(0); } inti_sendto(intfd,void*buf,size_tlen,intflags, structsockaddr*addr,intsize) { if(-1==sendto(fd,buf,len,flags,addr,size)) { perror("i_sendtoerror"); exit(1); } return(0); } inti_open(constchar*pathname,intflags) { intfd; if((fd=open(pathname,flags))==-1) { perror("open_failed"); exit(1); } return(fd); } inti_read(intfd,void*msg,intlen) { if(-1==read(fd,msg,len)) { perror("i_readerror"); exit(1); } return(0); } inti_write(intfd,void*msg,intlen) { if(-1==write(fd,msg,len)) { perror("i_writeerror"); exit(0); } return(0); } /*initasocket,fileandserveraddr*/ inti_init() { mainfd=i_open("./chat_log",O_RDWR|O_CREAT); sockfd=i_socket(AF_INET,SOCK_DGRAM,0); /*initializeserveraddress*/ bzero(&server,sizeof(server)); server.sin_family=AF_INET; inet_pton(AF_INET,"127.0.0.1",&server.sin_addr); server.sin_port=htons(SEVR_PORT); perror("init"); return(0); } char*i_get_time() { time_ttime_now; time(&time_now); return(ctime(&time_now)); } inti_lseek(intfd,off_tsize,intposition) { if(-1==lseek(fd,size,position)) { perror("seekerror"); exit(1); } return(0); } inti_saveto_chat(structmsg*pmsg) { structchat_historyhstr; bzero(&hstr,HSTR_LEN); count=count+1; hstr.count=count; hstr.from=pmsg->id_from; hstr.to=pmsg->id_to; strncpy(hstr.content,pmsg->content,CNTNT_LEN); strncpy(hstr.time,i_get_time(),25); i_lseek(mainfd,0,SEEK_END); i_write(mainfd,&hstr,HSTR_LEN); return(0); } inti_print_history(intlen,inti) { structchat_historychat_reader; intj; intposition; bzero(&chat_reader,HSTR_LEN); if(i!=0) { position=len*i*HSTR_LEN; i_lseek(mainfd,position,SEEK_END); } else { position=len*i*HSTR_LEN; i_lseek(mainfd,HSTR_LEN,SEEK_SET); } for(j=1;j<=len;j++) { i_read(mainfd,&chat_reader,HSTR_LEN); printf("\n#item%d:id%dtoid%d\n",j, chat_reader.from,chat_reader.to); i_print(chat_reader.content,CNTNT_LEN); printf("\nTime:%s\n",chat_reader.time); } return(0); } #endif
代码二:
#include"i.h" intuser_list_fd; /*start:initialization*/ intinit() { i_init(); user_list_fd=i_open("./user_list",O_RDWR|O_CREAT); structuserusr; /*inittheuserlistfile'sfistuserto0*/ memset((structuser*)&usr,'\0',sizeof(structuser)); i_lseek(user_list_fd,0,SEEK_SET); i_write(user_list_fd,(char*)&usr,USR_LEN); /*bindthestructsockaddr_inservertothesockfd*/ i_bind(sockfd,(structsockaddr*)&server,ADDR_LEN); structchat_historyapple; bzero(&apple,HSTR_LEN); i_lseek(mainfd,0,SEEK_SET); i_write(mainfd,&apple,HSTR_LEN); i_lseek(mainfd,-HSTR_LEN,SEEK_END); i_read(mainfd,&apple,HSTR_LEN); count=apple.count; return(0); } /*end:initialization*/ /*start:messagecontrol*/ intsend_msg(structmsg*msg_recv,structsockaddr*addr) { inti; structuserusr; /*acommonmessagecome*/ printf("aordinarmessagecome!\n"); i=msg_recv->id_to; i_lseek(user_list_fd,i*USR_LEN,SEEK_SET); i_read(user_list_fd,&usr,USR_LEN); strncpy(msg_recv->append,usr.name,10); i_sendto(sockfd,msg_recv,MSG_LEN,0, &(usr.user_addr),ADDR_LEN); printf("id%dsendamessagetoid%dsucess!\n",msg_recv->id_from,msg_recv->id_to); return(0); } intcheck_login(structmsg*msg_recv,structsockaddr*addr) { inti=msg_recv->id_from;; structuserusr; /*aloginrequet*/ printf("aloginrequestcome!\n"); /*gettheid'sinformation*/ i_lseek(user_list_fd,i*USR_LEN,SEEK_SET); i_read(user_list_fd,&usr,USR_LEN); intn; n=strcmp(usr.password,msg_recv->content); /*如果验证成功,则发送成功信息*/ if(n==0) { /*saveusernewaddress*/ i_lseek(user_list_fd,-USR_LEN,SEEK_CUR); usr.user_addr=*addr; i_write(user_list_fd,&usr,USR_LEN); /*telluserpass*/ i_sendto(sockfd,(structmsg*)msg_recv,sizeof(structmsg),0, &(usr.user_addr),ADDR_LEN); } else { /*出错的话的respond*/ if(0!=n) { printf("id%dloginerror.\n",i); bzero(msg_recv->content,CNTNT_LEN); msg_recv->flag=-1; i_sendto(sockfd,(structmsg*)msg_recv,sizeof(structmsg),0, &(usr.user_addr),ADDR_LEN); } return(1); } printf("Id%dloginsucess!\n",i); return(0); } intreg_user(structmsg*msg_recv,structsockaddr*addr) { structuserusr; printf("aregitrequetcome:\n"); /*findthelastuserandhavathepleasetoaddanewuser*/ intn; i_lseek(user_list_fd,-USR_LEN,SEEK_END); i_read(user_list_fd,&usr,USR_LEN); /*把新用户的信息赋值到usr然后填入到userlistfile中*/ constchar*name; constchar*password; name=&(msg_recv->content[0]); password=&(msg_recv->content[10]); strcpy((usr.name),name); strcpy(usr.password,password); memcpy(&(usr.user_addr),addr,ADDR_LEN); usr.id=(usr.id+1); i_lseek(user_list_fd,0,SEEK_END); i_write(user_list_fd,&usr,USR_LEN); msg_recv->id_from=usr.id; /*registtotheuserlistthentelltheuserregsuccess*/ i_sendto(sockfd,(structmsg*)msg_recv,sizeof(structmsg),0, addr,ADDR_LEN); printf("Id%dregistsucess!\n",usr.id); return(0); } intmsg_cntl() { structmsgmsg_recv; structsockaddraddr_recv; printf("beginlisteninput...\n"); intsize=ADDR_LEN; for(;;) { bzero(&msg_recv,MSG_LEN); i_recvfrom(sockfd,&msg_recv,sizeof(structmsg),0, &addr_recv,&size); printf("messagereceived...\n"); i_saveto_chat(&msg_recv); switch(msg_recv.flag) { case1: send_msg(&msg_recv,(structsockaddr*)&addr_recv);/*sendordinarychat*/ break; case2: check_login(&msg_recv,(structsockaddr*)&addr_recv); break; case3: reg_user(&msg_recv,(structsockaddr*)&addr_recv); break; default: break; } } return(0); } /*end:messagecontrol*/ /*start:exit_sys()*/ intexit_sys() { close(sockfd); close(mainfd); close(user_list_fd); printf("exitsystem"); kill(0,SIGABRT); exit(0); } /*end:exit_sys()*/ /*start:chat_history*/ intget_page_size() { structchat_historypage_size_reader; i_lseek(mainfd,-HSTR_LEN,SEEK_END); i_read(mainfd,&page_size_reader,HSTR_LEN); return(page_size_reader.count); } intread_chat_history() { printf("****char*history***"); printf("(n-nextpage;p-prepage;q-quit)\n"); intpage_num;/**/ intremains; intberry=get_page_size(); page_num=berry/8; remains=berry%8; if(remains!=0) page_num++; else page_num=page_num; printf("thereare%dpagetotal%ditems", page_num,berry); inti=-1; while(1) { charflag; if((berry+i*8)>=0) { printf("(%d~%d)\n",(berry+i*8),(berry+(i+1)*8)); i_print_history(PRT_LEN,i); printf("@@@\n"); while('\n'==(flag=getchar())) { } switch(flag) { case'p': i--; break; case'n': i++; break; case'q': return(0); default: break; } if(i>=0) { printf("haveattheend!\n"); printf("returntomenu!\n"); } } else { printf("(1~%d)\n",remains); i_print_history(remains,0); printf("#########over##############\n"); return(0); } } return(0); } /*end:chat_history*/ /*start:menu*/ intmenu() { sleep(1); printf("----------help----menu---------\n"); printf("\tr--reporttouser\n"); printf("\tc--chathistory\n"); printf("\th--helpmenu\n"); printf("\te--exitthesystem\n"); printf("----------help_menu---------\n"); intcommand=0; printf("inputcommand>"); command=getchar(); switch(command) { case'c': read_chat_history(); break; case'e': exit_sys(); break; case'r': //report(); //break; default: menu(); break; } getchar(); return(0); } /*end:menu*/ intmain() { init(); pid_tpid; switch(pid=fork()) { case-1: perror("forkerror\n"); exit(1); break; case0: msg_cntl(); break; default: menu(); break; } return(0); }
代码三:
#include"i.h" #defineSTART_PORT8089 structsockaddr_inmy_addr; intmy_id; intmy_log();/*declarefuntion*/ /**/ inti_send_msg() { intid; structmsgthe_msg; charend='@'; printf("inputrecverid:"); scanf("%d",&id); getchar(); printf("\ninputcontent:"); i_input(the_msg.content); charflag='y'; if(1) { the_msg.flag=1; the_msg.id_from=my_id; the_msg.id_to=id; i_sendto(sockfd,&the_msg,sizeof(structmsg),0, (structsockaddr*)&server,sizeof(structsockaddr)); i_saveto_chat(&the_msg);/*savetohistory*/ printf("sendtoid:%dsuccess.\n",my_id); return(0); } else return(1); return(0); } intreply() { return(0); } intsend_file() { return(0); } /**/ /*start:initialize*/ intinit() { structifreqreq; structsockaddr_in*host; intport; i_init(); /*inituseraddr*/ bzero(&my_addr,sizeof(structsockaddr)); my_addr.sin_family=AF_INET; strcpy(req.ifr_name,"lo"); if(ioctl(sockfd,SIOCGIFADDR,&req)<0)/*getlocalipaddress*/ { perror("getlocaliperror"); exit(1); } host=(structsockaddr_in*)&(req.ifr_addr); printf("ip:%s\n",inet_ntoa(host->sin_addr)); memcpy(&my_addr,(structsockaddr_in*)&(req.ifr_addr), sizeof(structsockaddr_in)); port=START_PORT; do { port++; my_addr.sin_port=htons(port); bind(sockfd,(structsockaddr*)&my_addr, sizeof(structsockaddr)); } while(errno==EADDRINUSE); structchat_historyapple; memset(&apple,'b',HSTR_LEN); i_lseek(mainfd,0,SEEK_SET); apple.count=0; i_write(mainfd,&apple,HSTR_LEN); i_lseek(mainfd,-HSTR_LEN,SEEK_END); i_read(mainfd,&apple,HSTR_LEN); count=apple.count; printf("port:%d\n",port); printf("initsuccessful!!!\n"); return(0); } /*end:initialize*/ /*start:chat_history*/ intget_page_size() { structchat_historypage_size_reader; i_lseek(mainfd,-HSTR_LEN,SEEK_END); i_read(mainfd,&page_size_reader,HSTR_LEN); return(page_size_reader.count); } intread_chat_history() { printf("****char*history***"); printf("(n-nextpage;p-prepage;q-quit)\n"); intpage_num;/**/ intremains; intberry=get_page_size(); page_num=berry/8; remains=berry%8; if(remains!=0) page_num++; else page_num=page_num; printf("thereare%dpagetotal%ditems", page_num,berry); inti=-1; while(1) { charflag; if((berry+i*8)>=0) { printf("(%d~%d)\n",(berry+i*8),(berry+(i+1)*8)); i_print_history(PRT_LEN,i); printf("@@@\n"); while('\n'==(flag=getchar())) { } switch(flag) { case'p': i--; break; case'n': i++; break; case'q': return(0); default: break; } if(i>=0) { printf("haveattheend!\n"); printf("returntomenu!\n"); } } else { printf("(1~%d)\n",remains); i_print_history(remains,0); printf("#########over##############\n"); return(0); } } return(0); } /*end:chat_history*/ /*start:exit_sys*/ voidexit_sys() { close(sockfd); close(mainfd); kill(0,SIGABRT); exit(0); } /*end:exit_sys*/ /*start:menu*/ intprint_menu() { printf("\n--------------help--menu----------------\n"); printf("\th--helpmunu\n"); printf("\ts--sendmessage\n"); printf("\tr--replyto\n"); printf("\tc--chathistory\n"); printf("\tf--sendfiles\n"); printf("\te--exitthesystem\n"); printf("----------------help--menu----------------\n"); } intget_input(char*command) { printf(">"); scanf("%c",command); return(1); } intmenu() { /*toavoidtheoutputatmixedwiththesubprocess*/ sleep(1); print_menu(); charcommand; while(1==get_input(&command)) { switch(command) { case'h': print_menu(); break; case's': i_send_msg(); break; case'r': reply(); break; case'f': send_file(); break; case'c': read_chat_history(); break; case'e': exit_sys(); break; default: printf(">"); break; } } return(0); } /*end:menu*/ /*start:messagecontol:send_msgandrecv_msg*/ intordnary_msg_recv(structmsg*pmsg) { chartime_info[25]; charend_symble; end_symble='&'; /*handlethemsg*/ printf("Message:from%s(id%d)toU:\n",pmsg->append,pmsg->id_from); i_print(pmsg->content,MSG_LEN); printf("\n\t%s",i_get_time()); return(0); } intfile_msg_recv(structmsg*pmsg) { } inthandle_msg(structmsg*pmsg) { if(pmsg->flag==1) { ordnary_msg_recv(pmsg); return(0); } elseif(pmsg->flag>=4) { file_msg_recv(pmsg); return(0); } return(0); } intlisten_msg() { structmsgmsg_recv; structsockaddraddr_recv; intlen=ADDR_LEN; printf("beginlisten...\n"); for(;;) { i_recvfrom(sockfd,&msg_recv,MSG_LEN,0, &addr_recv,&len); i_saveto_chat(&msg_recv);/*savetohistory*/ ordnary_msg_recv(&msg_recv); } } /*end:messagecontol*/ /*start:logprocess:loginandregist*/ intlogin() { /*inputid:*/ printf("*****login>>\n"); printf("id:"); scanf("%d",&my_id); /*inputpassword*/ charpassword[15]; printf("\npassword(*less15char):"); scanf("%s",password); getchar(); /*sendlogininformation*/ structmsglog_msg; bzero(&log_msg,MSG_LEN); log_msg.flag=2; log_msg.id_from=my_id; log_msg.id_to=0; strncpy(log_msg.content,password,15); i_saveto_chat(&log_msg);/*savetohistory*/ i_sendto(sockfd,(structmsg*)&log_msg,MSG_LEN,0, (structsockaddr*)&server,sizeof(structsockaddr)); //printf("log_msg:%d\n",log_msg.id_from); //printf("password:%s\n",log_msg.content); /*afterinputmsg,waitforserverrespond*/ structsockaddrin_addr; intlen=ADDR_LEN; i_recvfrom(sockfd,(structmsg*)&log_msg,MSG_LEN,0, &in_addr,&len); if(2==log_msg.flag) { printf("loginsuccess\n"); return(0); } else { printf("loginerror:%s\n",log_msg.content); printf("pleaserelog..\n"); menu(); } return(0); } intregist() { printf("*****regist>>\n"); /*inputchatname*/ charname[10]; bzero(name,10); printf("inputyourchatname(less8char):"); scanf("%s",name); //name[9]=';';/*adda;symbolintheendofname*/ /*inputpassword*/ charpassword[15]; bzero(password,15); printf("\ninputyourpassword(less14char):"); scanf("%s",password); /*sendregistinformation*/ structmsgreg_msg; bzero(®_msg,MSG_LEN); reg_msg.flag=3; reg_msg.id_from=0; reg_msg.id_to=0; bzero(reg_msg.content,CNTNT_LEN); strncpy(reg_msg.content,name,10); strncpy(&(reg_msg.content[10]),password,15); reg_msg.content[25]='\n'; i_saveto_chat(®_msg);/*savetohistory*/ /*sendregistinformatintoserver*/ i_sendto(sockfd,(structmsg*)®_msg,sizeof(structmsg),0, (structsockaddr*)&server,ADDR_LEN); /*afterinputmsg,waitforserverrespond*/ printf("watingforserverreply...\n"); structsockaddrin_addr; structmsgmsg_back; intlen=ADDR_LEN; bzero(&in_addr,ADDR_LEN); bzero(&msg_back,MSG_LEN); i_recvfrom(sockfd,(structmsg*)&msg_back,MSG_LEN,0, &in_addr,&len); /*checkwhetherpass*/ if(3!=msg_back.flag) { printf("error:%s\n",msg_back.content); exit(1); } else my_id=msg_back.id_to; printf("congratulate!youhaveregist" "id%s(id%d)success\n",msg_back.content,msg_back.id_to); login(); return(0); } intmy_log() { /*chooseloginorregist*/ charflag; printf("areyouwantloginorregist(l/r)\n"); scanf("%c",&flag); getchar(); switch(flag){ case'l': login(); break; case'r': regist(); break; default: printf("errorinput\n"); my_log(); break; } return(0); } /*end:log*/ intmain() { init(); printf("\n************welcome!************\n"); my_log(); pid_tpid; switch(pid=fork()) { case-1: perror("forkerror!\n"); exit(1); break; case0: listen_msg(); break; default: menu(); break; } }
希望本文所述对大家实现linux多人聊天室程序。