




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
Linux操作系統(tǒng)與程序設(shè)計課程設(shè)計報告書指導(dǎo)老師:報告組員:2023年7月5號TOC\o"1-3"\u目錄一、實驗工程目的1二、實驗工程的人員組成及指責(zé)劃分1三、實驗工程的功能及模塊劃分1四、設(shè)計與實現(xiàn)34.1系統(tǒng)結(jié)構(gòu)34.1.1系統(tǒng)結(jié)構(gòu)圖34.2客戶端界面34.2.1注冊34.2.2登錄44.2.3界面設(shè)計44.3效勞器的實現(xiàn)64.3.1用戶登錄64.3.2轉(zhuǎn)發(fā)聊天消息74.4通信模塊的實現(xiàn)84.4.1通信方式的選擇11五、測試與調(diào)試11六、總結(jié)11七、附錄:程序代碼12一.實驗工程目的隨著嵌入式在生活年中的應(yīng)用越來越廣泛,嵌入式Linux下的socket網(wǎng)絡(luò)編程也越來越熱門。本次課程設(shè)計是為了加強對LINUX系統(tǒng)下的編程的各種知識點的整合與靈活運用,讓我們更加熟悉Linux下的編程操作,重點在Linux下的socket編程,了解TCP,UDP等協(xié)議的使用,并完成課程設(shè)計題目。二.實驗工程的人員組成及指責(zé)劃分我們實驗組總共由2個同學(xué)組成,姓名,專業(yè),學(xué)號及職責(zé)劃分如下:=1\*GB3①〔專業(yè)及班級:網(wǎng)絡(luò)工程102班學(xué)號:1〕,小組組長,負責(zé)整體設(shè)計和模塊劃分。=2\*GB3②〔專業(yè)班級:網(wǎng)絡(luò)工程102班,學(xué)號:13〕,負責(zé)代碼編寫及修改.三.實驗工程的功能及模塊劃分1.系統(tǒng)功能系統(tǒng)主要實現(xiàn)三大功能:1.注冊與登陸系統(tǒng)2.群聊3.私聊2.登錄聊天系統(tǒng)功能模塊圖客戶端登錄聊天系統(tǒng)私聊退出群聊私聊退出群聊解除鎖定直接私聊鎖定私聊對象解除鎖定直接私聊鎖定私聊對象聊天系統(tǒng)效勞器聊天系統(tǒng)登錄處理關(guān)閉效勞器聊天信息發(fā)送處理用戶退出用戶管理四、設(shè)計與實現(xiàn)登錄處理關(guān)閉效勞器聊天信息發(fā)送處理用戶退出用戶管理4.1系統(tǒng)結(jié)構(gòu)4.1.1系統(tǒng)結(jié)構(gòu)圖發(fā)送消息發(fā)送消息模塊發(fā)送消息發(fā)送消息模塊效勞器轉(zhuǎn)發(fā)消息建立用戶鏈表,執(zhí)行添加用戶,刪除用戶,查詢用戶等操作。效勞器轉(zhuǎn)發(fā)消息建立用戶鏈表,執(zhí)行添加用戶,刪除用戶,查詢用戶等操作??蛻舳丝蛻舳私邮芟⒛K接受消息模塊接受消息接受消息4.2客戶端界面4.2.1注冊4.2.2登錄登錄界面設(shè)計截圖4.2.2界面設(shè)計界面截圖本系統(tǒng)直接在終端環(huán)境下運行,具體實現(xiàn)代碼如下:while(1){ memset(buf,'\0',BUFFERSIZE);//必須清空否那么會有虛假數(shù)據(jù) memset(buf_temp,'\0',BUFFERSIZE); if(recvfrom(socket_fd,buf,sizeof(buf),0,NULL,NULL)<0){ perror("接收消息失敗"); } if(strncmp("Q",buf,1)==0)//接收效勞器下線通知 { printf("\033[22;30m%s",buf+1);//輸出黑色文字系統(tǒng)消息 kill(getppid(),SIGUSR2); kill(getpid(),SIGUSR2); } elseif(strncmp("A",buf,1)==0) { printf("\033[22;96m%s",buf+1);//輸出灰色文字系統(tǒng)消息 } elseif(strncmp("P",buf,1)==0) { printf("\033[22;31m%s",buf+1);//輸出紅色文字系統(tǒng)消息 } elseif(strncmp("R",buf,1)==0) { if(strncmp(buf+1,name,strlen(name))==0) { sprintf(buf_temp,"我%s",buf+strlen(name)+1); printf("\033[22;32m%s",buf_temp);//輸出黃色文字自己的消息 } else{ printf("\033[22;33m[收到消息@]%s",buf+1);//輸出綠色文字} } printf("\033[22;30m");//恢復(fù)黑色 }4.3效勞器的實現(xiàn)效勞器運行界面:4.3.1用戶登錄處理用戶登錄功能源碼:voidProcessLogin(char*command,SA_INrec_addr){ charname[10]; USERuser; charbuf[BUFFERSIZE]; memset(buf,'\0',BUFFERSIZE); strcpy(name,command+1); if(findUser(head,name)==-1){ strcpy(,name); user.address=rec_addr; addUser(head,user); buf[0]='Y'; if(sendto(socket_fd,buf,sizeof(buf),0,(SA*)&rec_addr,sizeof(rec_addr))==-1) { perror("登錄失敗"); } } else{ buf[0]='N'; if(sendto(socket_fd,buf,sizeof(buf),0,(SA*)&rec_addr,sizeof(rec_addr))==-1) { perror("登錄失敗"); } }}4.3.2轉(zhuǎn)發(fā)聊天消息界面:源碼:voidProcessChat(char*command){ charbuf[BUFFERSIZE]; SA_INaddress; memset(buf,'\0',BUFFERSIZE);printf("server09\n!!");//******* sprintf(buf,"R%s\n<請輸入>\n",command+1);//'\n'強行推送數(shù)據(jù) 必須否那么要到緩沖區(qū)滿才一次性發(fā)送printf("server9\n!!");//******* plinkp=head->next; while(p!=NULL){ address=(p->data).address; if(sendto(socket_fd,buf,sizeof(buf),0,(SA*)&address,sizeof(address))<0) { perror("消息發(fā)送失敗"); } p=p->next; }}4.4通信模塊的實現(xiàn)在客戶端,使用了兩個進程,主進程負責(zé)登錄和發(fā)送消息,子進程負責(zé)接受消息并處理消息。發(fā)送消息代碼如下:while(1)//父進程 { memset(buf,'\0',BUFFERSIZE);//必須清空否那么會有虛假數(shù)據(jù) memset(buf_temp,'\0',BUFFERSIZE); fgets(buf_temp,BUFFERSIZE,stdin); //采用fgets比采用scanf好,聊天時可以鍵入空格 buf_temp[strlen(buf_temp)]='\0'; if(strncmp("unlock",buf_temp,6)==0)//解除鎖定某個好友 { islock=0; printf("解除鎖定\n"); } if(strncmp("&",buf_temp,1)==0)//鎖定某個好友 { islock=1; buf_temp[0]='$'; buf_temp[strlen(buf_temp)-1]='$'; strcpy(sname,buf_temp); printf("當(dāng)前已經(jīng)鎖定好友為%s,解除鎖定清輸入unlock\n",sname); buf_temp[strlen(buf_temp)]='h'; buf_temp[strlen(buf_temp)+1]='i'; buf_temp[strlen(buf_temp)+2]='\0'; } if(islock==1){ chars[1024]; strncat(s,sname,strlen(sname)); strncat(s,buf_temp,strlen(buf_temp)); strcpy(buf_temp,s); strcpy(s,""); } if(strncmp("quit",buf_temp,4)==0)//退出 { sprintf(buf,"Q%s",name); quit_flag=1; } elseif(strncmp("$",buf_temp,1)==0)//注:發(fā)送悄悄話的格式:$對方名稱$消息內(nèi)容 { char*check=buf_temp+1; //必須對其檢查一定要有兩個$...$否那么造成效勞器當(dāng)機 while(*check!='\0'&&*check!='$') check++; if(*check!='$') { printf("[系統(tǒng)提示]\n發(fā)送悄悄話格式:$對方名稱$消息內(nèi)容\n<請輸入>\n"); continue; } sprintf(buf,"P%s%s",name,buf_temp); } else//群發(fā)消息 { if(strncmp("online",buf_temp,6)==0)//獲取所有好友 { sprintf(buf,"A%s",name); }elseif(strncmp("help",buf_temp,4)==0){ printf("===歡送使用本聊天系統(tǒng)===\n"); printf("功能說明\n"); printf("1:群聊,直接輸入信息即可\n"); printf("2:輸入[$+好友名稱+$+私聊信息]進行私聊\n"); printf("3:輸入quit,退出本系統(tǒng)\n"); printf("4:輸入&+好友名稱可以進入與該好友私聊狀態(tài)\n"); printf("5:輸入unlock解除好友私聊狀態(tài)\n"); printf("6:輸入online獲取所有在線好友信息\n"); printf("7:輸入help獲取幫助信息\n"); printf("===歡送使用本聊天系統(tǒng)===\n"); sprintf(buf,"H%s",name); }else{ sprintf(buf,"C%s說:%s",name,buf_temp); } } //開始發(fā)送消息 if(sendto(socket_fd,buf,sizeof(buf),0,(SA*)&serv_addr, sizeof(serv_addr))<0) { perror("發(fā)送失敗"); } if(quit_flag) { kill(pid,SIGUSR2); break; } }接受消息代碼如下:while(1){ memset(buf,'\0',BUFFERSIZE);//必須清空否那么會有虛假數(shù)據(jù) memset(buf_temp,'\0',BUFFERSIZE); if(recvfrom(socket_fd,buf,sizeof(buf),0,NULL,NULL)<0){ perror("接收消息失敗"); } if(strncmp("Q",buf,1)==0)//接收效勞器下線通知 { printf("\033[22;30m%s",buf+1);//輸出黑色文字系統(tǒng)消息 kill(getppid(),SIGUSR2); kill(getpid(),SIGUSR2); } elseif(strncmp("A",buf,1)==0) { printf("\033[22;96m%s",buf+1);//輸出灰色文字系統(tǒng)消息 } elseif(strncmp("P",buf,1)==0) { printf("\033[22;31m%s",buf+1);//輸出紅色文字系統(tǒng)消息 } elseif(strncmp("R",buf,1)==0) { if(strncmp(buf+1,name,strlen(name))==0) { sprintf(buf_temp,"我%s",buf+strlen(name)+1); printf("\033[22;32m%s",buf_temp);//輸出黃色文字自己的消息 } else{ printf("\033[22;33m[收到消息@]%s",buf+1);//輸出綠色文字} } printf("\033[22;30m");//恢復(fù)黑色 }4.4.1通信方式的選擇本系統(tǒng)使用udp通信方式,效勞器必須指定端口號和ip地址,客戶端根據(jù)該端口號和ip地址找到效勞器并建立連接,數(shù)據(jù)發(fā)送采用數(shù)據(jù)包格式。他的優(yōu)點是,效率高,缺點是不可靠。測試與調(diào)試登錄時,判斷是否已經(jīng)登錄,還有判斷是否存在賬號,編寫登錄或注冊菜單界面時,編寫的測試類以此來測試,輸入一些非法數(shù)據(jù)來測試客服端有沒有過濾他們總結(jié)本次課程設(shè)計順利完成了Linux下聊天室工具的設(shè)計,包括登陸,私聊等功能,其中聊天時可以用英文以及中文聊天,可以通過輸入$好友名稱$信息和某個好友聊天,解除好友時輸入unlock??蛻暨€可以輸入help獲得幫助的信息,功能相對完善。在本次課程設(shè)計,實現(xiàn)各個局部功能的程序都比擬復(fù)雜,需要利用linux下的socket網(wǎng)絡(luò)編程知識和大量編程技巧,不過這使得我們在課程設(shè)計中,學(xué)到了很多東西。通過本次的課程設(shè)計,我們的軟件開發(fā)能力在一定程度上提高了,對Linux程序設(shè)計著門課程有了較深刻的了解,實驗過程中我們也遇到了很多問題,但是團隊合作的力量,讓問題在我們面前都顯的那么無力。同伴們在一起討論,研究,一起上網(wǎng)查資料,查書,以及向老師請教,問題都一一的解決了。在這里,我們深刻的感受到團隊的強大的力量,不僅讓我們敢于直面問題,更讓我們在快樂互助中學(xué)到很多的東西。這次的課程設(shè)計,再次教會了我們?nèi)绾谓涣鳎献髋c互助,加強了團隊合作的意識。我們的程序可以完成登陸,私聊等根本功能。但是由于所學(xué)的知識不全面,時間限制,我們沒有完成更高的功能,不過之后我們會繼續(xù)學(xué)習(xí),改善我們的系統(tǒng),努力做的更好!總之,這次的課程設(shè)計使我們滿載而歸,也讓我們深刻的懂得,用心做,總是會有回報的!我們會繼續(xù)加油的!附錄:程序代碼客戶端:#include<stdio.h>#include<stdlib.h>#include<unistd.h>#include<string.h>#include<fcntl.h>#include<dirent.h>#include<sys/types.h>#include<sys/socket.h>#include<netinet/in.h>#include<arpa/inet.h>#include<errno.h>#include<netdb.h>#include<signal.h>#include<stdlib.h>#include"mysql.h"#defineBUFFERSIZE1024typedefstructsockaddrSA;typedefstructsockaddr_inSA_IN;#defineSERVER_IP""#defineSERVER_PORT8000voidsig_user1(intsigno);voidsig_user2(intsigno);voidsig_alrm(intsigno);char*ProcessLogin(SA_INserv_addr);//以下為功能函數(shù)聲明voiddispDot();voidpt_msg();intmsSleep(longms);voiddenglu();staticpid_tpid;staticintsocket_fd;chars3[50];intmain(void){ intislock=0; charsname[1024]; charbuf[BUFFERSIZE];//定義一個字節(jié)的緩沖區(qū) charbuf_temp[BUFFERSIZE];//定義一個字節(jié)的臨時緩沖區(qū) charname[10];//姓名 SA_INserv_addr;//效勞器地址 signal(SIGUSR1,sig_user1);//signal的意思是 signal(SIGUSR2,sig_user2); signal(SIGINT,SIG_IGN);//拒絕用戶ctrl+c強制退出,只能鍵入quit退出 if((socket_fd=socket(AF_INET,SOCK_DGRAM,0))==-1){ perror("套接字創(chuàng)立失敗"); exit(-1); }//效勞器配置信息 memset(&serv_addr,0,sizeof(serv_addr)); serv_addr.sin_family=AF_INET; serv_addr.sin_addr.s_addr=inet_addr(SERVER_IP); serv_addr.sin_port=htons(8000); //pt_msg(); strcpy(name,ProcessLogin(serv_addr));//得到登錄名 if((pid=fork())==-1) { perror("子進程創(chuàng)立失敗"); return-1; } if(pid==0)///////////////////////////////////子進程,用來接收效勞器的消息 { memset(buf,'\0',BUFFERSIZE);//必須清空否那么會有虛假數(shù)據(jù) memset(buf_temp,'\0',BUFFERSIZE); sprintf(buf,"C%s上線了",name); if(sendto(socket_fd,buf,sizeof(buf),0,(SA*)&serv_addr, sizeof(serv_addr))<0) { perror("上線失敗"); } sleep(1); kill(getppid(),SIGUSR1);//喚醒主進程讓其輸入 while(1){ memset(buf,'\0',BUFFERSIZE);//必須清空否那么會有虛假數(shù)據(jù) memset(buf_temp,'\0',BUFFERSIZE); if(recvfrom(socket_fd,buf,sizeof(buf),0,NULL,NULL)<0) { perror("接收消息失敗"); } if(strncmp("Q",buf,1)==0)//接收效勞器下線通知 { printf("\033[22;30m%s",buf+1);//輸出黑色文字系統(tǒng)消息 kill(getppid(),SIGUSR2); kill(getpid(),SIGUSR2); } elseif(strncmp("A",buf,1)==0) { printf("\033[22;96m%s",buf+1);//輸出灰色文字系統(tǒng)消息 } elseif(strncmp("P",buf,1)==0) { printf("\033[22;31m%s",buf+1);//輸出紅色文字系統(tǒng)消息 } elseif(strncmp("R",buf,1)==0) { if(strncmp(buf+1,name,strlen(name))==0) { sprintf(buf_temp,"我%s",buf+strlen(name)+1); printf("\033[22;32m%s",buf_temp);//輸出黃色文字自己的消息 } else{ printf("\033[22;33m[收到消息@]%s",buf+1);//輸出綠色文字} } printf("\033[22;30m");//恢復(fù)黑色 } } //////////////////////////////////////////////////////主進程//////////////////////////////////// pause(); //等待SIGUSR1 intquit_flag=0; getchar();//清空輸入名字時殘存的回車符,因為ProcessLogin使用scanf while(1)//父進程 { memset(buf,'\0',BUFFERSIZE);//必須清空否那么會有虛假數(shù)據(jù) memset(buf_temp,'\0',BUFFERSIZE); fgets(buf_temp,BUFFERSIZE,stdin); //采用fgets比采用scanf好,聊天時可以鍵入空格 buf_temp[strlen(buf_temp)]='\0'; if(strncmp("unlock",buf_temp,6)==0)//解除鎖定某個好友 { islock=0; printf("解除鎖定\n"); } if(strncmp("&",buf_temp,1)==0)//鎖定某個好友 { printf("1-------------\n"); islock=1; buf_temp[0]='$'; buf_temp[strlen(buf_temp)-1]='$'; printf("2-------------\n"); //strcpy(sname,buf_temp); sprintf(sname,"%s",buf_temp); printf("*-------------\n"); printf("當(dāng)前已經(jīng)鎖定好友為%s,解除鎖定清輸入unlock\n",sname); printf("3-------------\n"); buf_temp[strlen(buf_temp)]='h'; buf_temp[strlen(buf_temp)+1]='i'; buf_temp[strlen(buf_temp)+2]='\0'; printf("4-------------\n"); } if(islock==1){ chars[1024]; strncat(s,sname,strlen(sname)); strncat(s,buf_temp,strlen(buf_temp)); strcpy(buf_temp,s); strcpy(s,""); } if(strncmp("quit",buf_temp,4)==0)//退出 { sprintf(buf,"Q%s",name); quit_flag=1; } elseif(strncmp("$",buf_temp,1)==0)//注:發(fā)送悄悄話的格式:$對方名稱$消息內(nèi)容 { char*check=buf_temp+1; //必須對其檢查一定要有兩個$...$否那么造成效勞器當(dāng)機 while(*check!='\0'&&*check!='$') check++; if(*check!='$') { printf("[系統(tǒng)提示]\n發(fā)送悄悄話格式:$對方名稱$消息內(nèi)容\n<請輸入>\n"); continue; } sprintf(buf,"P%s%s",name,buf_temp); } else//群發(fā)消息 { if(strncmp("online",buf_temp,6)==0)//獲取所有好友 { sprintf(buf,"A%s",name); } elseif(strncmp("help",buf_temp,4)==0) { pt_msg(); sprintf(buf,"H%s",name); } else { sprintf(buf,"C%s說:%s",name,buf_temp); } } //開始發(fā)送消息 if(sendto(socket_fd,buf,sizeof(buf),0,(SA*)&serv_addr, sizeof(serv_addr))<0) { perror("發(fā)送失敗"); } if(quit_flag) { kill(pid,SIGUSR2); break; } } kill(getpid(),SIGUSR2);}voidsig_user2(intsigno){ printf("%d進程結(jié)束\n",getpid()); exit(-1);}voidsig_user1(intsigno){ ;}voidsig_alrm(intsigno){ return;}char*ProcessLogin(SA_INserv_addr){ charbuf[10]; staticcharname[10]; structsigactionact; //處理效勞器未上線 sigaction(SIGALRM,NULL,&act); act.sa_handler=sig_alrm; act.sa_flags&=~SA_RESTART; //有何用處?????? sigaction(SIGALRM,&act,NULL); while(1){ denglu(); //printf("請輸入用戶名:"); buf[0]='L'; //scanf("%s",buf+1); strcpy(name,s3); strcpy(buf+1,s3); alarm(2);//設(shè)置連接效勞器超時時間為2秒 printf("登錄中"); dispDot(); if(sendto(socket_fd,buf,sizeof(buf),0,(SA*)&serv_addr, sizeof(serv_addr))<0) { perror("登錄失敗"); } recvfrom(socket_fd,buf,sizeof(buf),0,NULL,NULL); if(buf[0]=='N'){ printf("該用戶名已被使用,請重新輸入用戶名\n"); }elseif(buf[0]=='Y'){ printf("%s登錄成功\n",name); pt_msg(); alarm(0);//必須關(guān)閉鬧鐘 returnname; break; } else { printf("效勞器未上線,退出登錄\n"); exit(-1); } }}voidpt_msg(){printf("\n(歡送使用QQ聊天室\n"); printf("***********************************************************************\n"); printf("1:輸入信息〔單用戶直接輸入)進行多人聊天\n"); printf("2:輸入信息($+對象名+$+信息)進行聊天\n"); printf("3:輸入信息(用戶輸入quit)退出本系統(tǒng)\n"); printf("4:輸入信息(&+對象名)與好友聊天\n"); printf("5:輸入信息(用戶輸入unlock)解除好友聊天\n"); printf("6:輸入信息(用戶輸入online)獲取在線好友信息\n"); printf("7:輸入信息(用戶輸入help)獲取幫助信息\n"); printf("***********************************************************************\n");}voiddispDot(){ inti; for(i=0;i<10;i++) { printf("."); fflush(stdout); msSleep(90000); } printf("\n");}intmsSleep(longms){structtimevaltv;tv.tv_sec=0;tv.tv_usec=ms;returnselect(0,NULL,NULL,NULL,&tv);}voiddenglu(){ MYSQLmy_connection; MYSQL_RES*res_ptr; MYSQL_ROWsqlrow; intres; mysql_init(&my_connection); chars1[250]; chars2[11]; charc; printf("a登錄"); printf("\nb注冊\n"); printf("請選擇.....\n"); scanf("%c",&c); if(c=='a') { printf("\n請輸入帳號:"); scanf("%s",&s2); printf("\n請輸入昵稱:"); scanf("%s",&s3); if(mysql_real_connect(&my_connection,"localhost","root","liuxu","qq",0,NULL,0)) { //printf("Connectionsuccess\n"); sprintf(s1,"selectnamefromuserwhereid='%s'",s2); res=mysql_query(&my_connection,s1); if(res) { printf("登錄失?。。?!"); exit(0); } else {//printf("登錄成功?。?); } } } if(c=='b') { printf("請輸入帳號:"); scanf("%s",&s2); printf("\n請輸入昵稱:"); scanf("%s",&s3); if(mysql_real_connect(&my_connection,"localhost","root","liuxu","qq",0,NULL,0)) { printf("Connectionsuccess\n"); sprintf(s1,"insertintouser(id,name)values('%s','%s')",s2,s3); res=mysql_query(&my_connection,s1); if(!res) { printf("Inserted%lurows\n",(unsignedlong)mysql_affected_rows(&my_connection)); printf("注冊成功?。?!"); }else { printf("注冊失??!"); exit(0); } } printf("\n請重輸?。?!"); } //exit(0);}效勞器:#include<stdio.h>#include<stdlib.h>#include<unistd.h>#include<string.h>#include<fcntl.h>#include<dirent.h>#include<sys/types.h>#include<sys/socket.h>#include<netinet/in.h>#include<arpa/inet.h>#include<errno.h>#include<netdb.h>#include<signal.h>#defineBUFFERSIZE1024typedefstructsockaddrSA;typedefstructsockaddr_inSA_IN;#defineSERVER_IP""#defineSERVER_PORT8000#include<time.h>typedefstruct{ charname[10]; SA_INaddress;}USER;//用戶鏈表typedefstructHnode_list{ USERdata; structHnode_list*next;}Hlink,*plink;intmemoryError(plinkp);intcreatUserList(plinkhead);//建立用戶鏈表intfindUser(plinkhead,charname[10]);//查找用戶intdelUser(plinkhead,charname[10]);//刪除用戶intgetAllUser(plinkconsthead);//得到所有用戶信息intaddUser(plinkhead,USERdata);//增加用戶//函數(shù)voidProcessLogin(char*command,SA_INrec_addr);//登錄函數(shù)voidProcessChat(char*command);//控制消息收送函數(shù)voidProcessQuit(char*command);//退出函數(shù)intProcessPrivate(char*command,SA_INrec_addr);//控制私談函數(shù)voidProcessAd();voidsig_int(intsignum);staticplinkhead;staticintsocket_fd;intmain(void){ charbuf[BUFFERSIZE]; SA_INaddress,rec_addr; socklen_tlength; structtimevaltv; tv.tv_sec=60; tv.tv_usec=0; head=malloc(sizeof(Hlink));//用戶列表頭 creatUserList(head);//創(chuàng)立列表 signal(SIGINT,sig_int);//ctr+c強制退出 if((socket_fd=socket(AF_INET,SOCK_DGRAM,0))==-1){//創(chuàng)立套接字 perror("套接字創(chuàng)立失敗"); exit(-1); } memset(&address,0,sizeof(address)); address.sin_family=AF_INET; address.sin_addr.s_addr=inet_addr(SERVER_IP); address.sin_port=htons(SERVER_PORT); if(bind(socket_fd,(SA*)&address,sizeof(address))==-1){ perror("套接字綁定失敗"); exit(-1); } //30秒沒有收到任何消息就發(fā)送消息//printf("server0\n!!");//******* printf("效勞器啟動成功ip:%s\n",inet_ntoa(address.sin_addr));//printf("server1\n!!");//******* length=sizeof(rec_addr); setsockopt(socket_fd,SOL_SOCKET,SO_RCVTIMEO,&tv,sizeof(tv));//sendSocket--一個翻開的套接口描述字//IPPROTO_IP或SOL_SOCKET--指定系統(tǒng)中解釋選項的代碼〔可取以下值:SOL_SOCKET或IPPROTO_IP或IPPROTO_ICMPV6或IPPROTO_IPV6或IPPROTO_TCP〕//IP_HDRINCL或SO_SNDTIMEO--本次調(diào)用要設(shè)置的選項名//flag或timeout--一個指向變量的指針,將該指針指向的對象設(shè)為上述選項名的新值//sizeof(flag)或sizeof(timeout)--變量的大小 while(1){printf("serverwhile\n!!");//******* memset(buf,0,sizeof(buf)); //效勞器只有此處用來接收 if(recvfrom(socket_fd,buf,sizeof(buf),0,(SA*)&rec_addr,&length) ==-1) { buf[0]='A';//發(fā)送標志位printf("server2\n!!");//******* } switch(buf[0]){ case'L': ProcessLogin(buf,rec_addr);printf("server3\n!!");//******* break; case'C': ProcessChat(buf);printf("server4\n!!");//******* break; case'Q': ProcessQuit(buf);printf("server5\n!!");//******* break; case'A': ProcessAd();printf("server6\n!!");//******* break; case'P': ProcessPrivate(buf,rec_addr);printf("server7\n!!");//******* break; case'H': printf("server7\n!!");//******* break; default: printf("ERROR");printf("server8\n!!");//******* break; } }}voidProcessLogin(char*command,SA_INrec_addr){ charname[10]; USERuser; charbuf[BUFFERSIZE]; memset(buf,'\0',BUFFERSIZE); strcpy(name,command+1); if(findUser(head,name)==-1){ strcpy(,name); user.address=rec_addr; addUser(head,user); buf[0]='Y'; if(sendto(socket_fd,buf,sizeof(buf),0,(SA*)&rec_addr,sizeof(rec_addr))==-1) { perror("登錄失敗"); } } else{ buf[0]='N'; if(sendto(socket_fd,buf,sizeof(buf),0,(SA*)&rec_addr,sizeof(rec_addr))==-1) { perror("登錄失敗"); } }}voidProcessChat(char*command){ charbuf[BUFFERSIZE]; SA_INaddress; memset(buf,'\0',BUFFERSIZE);printf("server09\n!!");//******* sprintf(buf,"R%s\n<請輸入>\n",command+1);//'\n'強行推送數(shù)據(jù) 必須否那么要到緩沖區(qū)滿才一次性發(fā)送printf("server9\n!!");//******* plinkp=head->next; while(p!=NULL){ address=(p->data).address; if(sendto(socket_fd,buf,sizeof(buf),0,(SA*)&address,sizeof(address))<0) { perror("消息發(fā)送失敗"); } p=p->next; }}voidProcessQuit(char*command){ charname[10]; charbuf[BUFFERSIZE]; memset(buf,'\0',BUFFERSIZE); SA_INaddress; sprintf(name,"%s",command+1); plinkp=head->next; delUser(head,name); sprintf(buf,"R%s下線了\n",name); while(p!=NULL){ address=(p->data).address; if(sendto(socket_fd,buf,sizeof(buf),0,(SA*)&address,sizeof(address))<0) { perror("消息發(fā)送失敗"); } p=p->next; }}voidProcessAd(){ charbuf[BUFFERSIZE]; charbuf_temp[BUFFERSIZE]; memset(buf,'\0',BUFFERSIZE);//必須清空否那么會有虛假數(shù)據(jù) memset(buf_temp,'\0',BUFFERSIZE); SA_INaddress; plinkp=head->next; strcat(buf,"A<<系統(tǒng)消息>>當(dāng)前在線用戶\n"); while(p!=NULL) { sprintf(buf_temp,"[%s:%s]",(p->data).name,inet_ntoa((p->data).address.sin_addr)); strcat(buf,buf_temp); p=p->next; }printf("server010\n!!");//******* strcat(buf,"\n<請輸入>\n");printf("server10\n!!");//******* p=head->next; while(p!=NULL){ address=(p->data).address;printf("server100\n!!");//******* if(sendto(socket_fd,buf,sizeof(buf),0,(SA*)&address,sizeof(address))<0) { perror("消息發(fā)送失敗"); } p=p->next; }}intProcessPrivate(char*command,SA_INrec_addr){ charbuf[BUFFERSIZE]; charbuf_temp[BUFFERSIZE]; charname_from[10]; charname_to[10]; intnon_user_flag=0; inti,j; for(i=1,j=0;command[i]!='$';i++,j++) { name_from[j]=command[i]; } name_from[j]='\0'; i++; for(j=0;command[i]!='$';i++,j++) {
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 電磁感應(yīng)模塊的高考物理試題分析與教學(xué)策略研究-以2013-2023年全國卷為例
- 新興版畫在當(dāng)代語境下的美育價值
- 海爾集團跨國并購意大利Candy風(fēng)險研究
- 盆地效應(yīng)建模研究及應(yīng)用
- 小班健康小花園
- 患者健康教育的應(yīng)用
- 羊水栓塞患者常規(guī)護理
- 生物教學(xué)設(shè)計
- 小學(xué)生電梯安全教育
- 保育員基礎(chǔ)知識第二版課件
- 自然生態(tài)探險之旅行業(yè)跨境出海項目商業(yè)計劃書
- 西藏自治區(qū)拉薩市達孜區(qū)孜縣2025年七下英語期中質(zhì)量檢測模擬試題含答案
- 遼寧省沈陽市2023?2024學(xué)年高二下冊期末考試數(shù)學(xué)試卷2附解析
- 廚師三級考試試題及答案
- 一例膿毒性休克個案護理
- 初級社工職業(yè)道德試題及答案
- T/CGCC 17-2018商業(yè)信譽評價體系
- 合作共贏的未來展望
- 2025年纏繞式玻璃鋼管道項目市場調(diào)查研究報告
- 項目運營授權(quán)協(xié)議書
- 2024北京豐臺區(qū)高二(下)期中政治(A卷)及答案
評論
0/150
提交評論