資源描述:
《UDP局域網(wǎng)聊天室實(shí)現(xiàn).pdf》由會(huì)員上傳分享,免費(fèi)在線閱讀,更多相關(guān)內(nèi)容在行業(yè)資料-天天文庫。
1、UDP局域網(wǎng)聊天室實(shí)現(xiàn)1.UDP聊天室基本功能分析2.UDP實(shí)現(xiàn)流程分析(客戶端,服務(wù)器)3.UDP聊天功能實(shí)現(xiàn)(群聊,私聊)4.總結(jié)1.UDP基本功能分析在學(xué)完網(wǎng)絡(luò)中UDP的編程之后,我們想通過實(shí)現(xiàn)一個(gè)UDP的聊天室來實(shí)際運(yùn)用一下~!那么聊天室需要哪些功能呢!我們可以類比QQ的聊天的功能,QQ最基本的功能:1.登錄注冊(cè)2.聊天3.退出那么我們也大致實(shí)現(xiàn)這些功能。我們做一些簡化,不需要登錄注冊(cè)的功能,登錄時(shí),給所有連接上來的客戶端發(fā)送消息,告訴說誰登錄上來了客戶端給服務(wù)器發(fā)送消息時(shí)就指定需要聊天
2、的對(duì)象。我們分析一下我們聊天的過程:(1).我們實(shí)心的效果是如:A---->B(A與B進(jìn)行聊天)A與B聊天實(shí)際上是A---“消息”--服務(wù)器轉(zhuǎn)發(fā)---"消息"---->B(2).服務(wù)器發(fā)送消息服務(wù)器-->A-->B--->C這是一個(gè)群發(fā)的消息2.UDP實(shí)現(xiàn)流程分析(客戶端,服務(wù)器)分析客戶端的流程:客戶端:整體的流程首先是網(wǎng)絡(luò)的基本編程socketpid=fork();if(pid>0)//父進(jìn)程,主要功能,數(shù)據(jù)發(fā)送{while(1){//大循環(huán)1.發(fā)送一個(gè)登錄的消息,告訴大家我上線了2..從鍵
3、盤獲得數(shù)據(jù)a.聊天的對(duì)端的名字SYSTERM群聊消息非SYSTERM私聊消息c.聊天的內(nèi)容d.輸入quit時(shí),結(jié)束3.聊天結(jié)束,發(fā)送一個(gè)聊天結(jié)束的消息給大家,告訴大家說我下線了}}}elseif(pid==0)//子進(jìn)程,主要功能,數(shù)據(jù)接收{(diào)while(1){1.接收數(shù)據(jù)2.顯示數(shù)據(jù)}}分析"服務(wù)器端"的流程:整體的流程是UDP的網(wǎng)絡(luò)服務(wù)器的基本編程socketbindpid=fork();if(pid>0)//父進(jìn)程發(fā)數(shù)據(jù),系統(tǒng)級(jí)別的消息,給所有客戶端發(fā)送消息{1.從鍵盤獲得數(shù)據(jù)2.發(fā)送給服務(wù)
4、器自己}elseif(pid==0)//子進(jìn)程,接收數(shù)據(jù),處理消息{1.接收發(fā)過來的消息2.根據(jù)消息類型進(jìn)行處理a.登錄消息b.退出消息d.群聊消息這三類消息都需要給每個(gè)客戶端發(fā)送e.私聊消息需要進(jìn)行指定聊天對(duì)象}分析數(shù)據(jù)結(jié)構(gòu)體:首先我們要考慮一個(gè)服務(wù)器端的程序如何給每個(gè)客戶端依次發(fā)送消息?1.UDP中如果向某個(gè)客戶端發(fā)送消息,那么我們需要指定對(duì)端的地址信息(ip+port)的信息那么服務(wù)器端如何保留這些客戶端的信息就是我們需要關(guān)注的問題?想想看如何可以實(shí)現(xiàn)?。。。。。。balabala那么我們
5、這里就用的非常廣泛的一種數(shù)據(jù)結(jié)構(gòu),鏈表來實(shí)現(xiàn)對(duì)客戶端地址信息的保留。鏈表的特點(diǎn),就不需要說了。我們這里主要關(guān)注其可以動(dòng)態(tài)增長的特點(diǎn)來使用那么這一問題解決之后,我們要做的就是實(shí)現(xiàn)相關(guān)的數(shù)據(jù)結(jié)構(gòu)的操作。那么我們分析一下該鏈表的數(shù)據(jù)結(jié)構(gòu)構(gòu)建。數(shù)據(jù)結(jié)構(gòu)地址信息節(jié)點(diǎn):typedefstructnode{structsockaddr_inaddr;structnodenext;}data_t;//消息類型#defineCLIENT_TALK100//私聊+clientname#defineSERVER_TA
6、LK200//給所有客戶端發(fā)送#defineCLIENT_LOGIN300//有客戶端登陸,地址存入鏈表#defineCLIENT_LOGOUT400//有客戶端退出,地址從鏈表刪除//消息結(jié)構(gòu)體typedefstruct{longtype;//消息類型charsrc_name[20];//自己客戶端名字,在運(yùn)行客戶端命令行指定名字chardst_name[20];//對(duì)方客戶端名字,在運(yùn)行客戶端命令行指定名字//客戶端登陸時(shí)給服務(wù)器發(fā)自己的名字和地址,/{{{///私聊時(shí)客戶端用于指定對(duì)方名字
7、,在服務(wù)器端可以根據(jù)名字找到對(duì)應(yīng)對(duì)方的地址//服務(wù)器端轉(zhuǎn)發(fā)私聊消息時(shí)如果要知道是誰發(fā)送,根據(jù)地址在鏈表中查找名字/}}}/charmtext[BUF_SZ];//消息正文}msg_t;分析函數(shù)實(shí)現(xiàn):服務(wù)器端:1.intsend_assign_client(intserfd,Linklisthead,msg_tpmsg);功能:通過名字查找對(duì)應(yīng)的客戶端是否存在,存在則發(fā)送消息不存在返回出錯(cuò)信息表示客戶端不存在給指定的客戶端發(fā)送消息參數(shù):@serfd進(jìn)行通信的socket對(duì)應(yīng)的文件描述符@head鏈
8、表的頭指針@pmsg指定的客戶端的名字返回值:0成功-1表示沒有找到對(duì)應(yīng)的客戶端2.broadcast_all_client(intserfd,Linklisthead,msg_tpmsg);功能:實(shí)現(xiàn)對(duì)每個(gè)客戶端發(fā)送消息參數(shù):同上返回值:0成功3.structsockaddr_infind_assign_client(Linklisthead,charname);功能:從鏈表中查找對(duì)應(yīng)名字的客戶端,找到之后返回其地址信息3.UDP聊天功能實(shí)現(xiàn)(群聊,私聊)//1.頭文件#ifndef_HEAD