CSU通信網原理課程設計_第1頁
CSU通信網原理課程設計_第2頁
CSU通信網原理課程設計_第3頁
CSU通信網原理課程設計_第4頁
CSU通信網原理課程設計_第5頁
已閱讀5頁,還剩56頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

/中南大學通信網原理課程設計報告班級:姓名:學號:指導老師:實驗地點:完成日期:電子信息工程系信息科學與工程學院目錄TOC\o”1-3”\h\uHYPERLINK\l_Toc25525第一部分:課程設計的目的與任務?PAGEREF_Toc255251HYPERLINK\l_Toc19359一、課程設計的目的?PAGEREF_Toc193591HYPERLINK\l_Toc23738二、課程設計的主要任務 PAGEREF_Toc237381HYPERLINK\l_Toc26063第二部分:滑動窗口協議仿真 PAGEREF_Toc260632HYPERLINK\l_Toc4242一、課程設計目的及要求 PAGEREF_Toc42422HYPERLINK\l_Toc3253二、設計思想?PAGEREF_Toc32532HYPERLINK\l_Toc30644三、設計流程圖 PAGEREF_Toc306442HYPERLINK\l_Toc23152四、開發環境?PAGEREF_Toc231524HYPERLINK\l_Toc16707五、關鍵代碼分析?PAGEREF_Toc167074HYPERLINK\l_Toc12584六、仿真運行 PAGEREF_Toc1258410HYPERLINK\l_Toc16395第三部分:網絡即時通訊程序 PAGEREF_Toc1639512HYPERLINK\l_Toc21659一、課程設計目的及要求?PAGEREF_Toc2165912HYPERLINK\l_Toc31858二、設計思想?12HYPERLINK\l_Toc6344三、設計流程圖?PAGEREF_Toc634413HYPERLINK\l_Toc31455四、開發環境?PAGEREF_Toc3145514HYPERLINK\l_Toc5951五、關鍵代碼分析?PAGEREF_Toc595114HYPERLINK\l_Toc611六、運行與調試?PAGEREF_Toc61120HYPERLINK\l_Toc10141第四部分:課程設計心得體會?PAGEREF_Toc1014123HYPERLINK\l_Toc19883第五部分:參考文獻 PAGEREF_Toc1988324HYPERLINK\l_Toc32061第六部分:附錄?PAGEREF_Toc3206124HYPERLINK\l_Toc8325一、滑動窗口協議仿真 PAGEREF_Toc832524HYPERLINK\l_Toc6953二、網絡即時通訊程序?PAGEREF_Toc695333第一部分:課程設計的目的與任務一、課程設計的目的通信網原理課程設計是為電子信息工程專業本科生開設的必修課,有2學分,既是對《通信網原理》課程實驗教學環節的補充,又是一門實踐性很強的綜合強化訓練課程。計算機網絡或Internet網已成為現代最重要的通信網,未來各種通信網都將以計算機網絡和IP協議為核心實現互連互通.因此,本課程設計的主要任務是在掌握計算機網絡TCP/IP等典型協議原理的基礎上,通過編程設計對網絡協議或算法進行模擬實現,并應用相應網絡協議來開發一個網絡應用系統。其目的是通過將理論與實踐相結合,使學生進一步深入理解通信網的工作原理,掌握網絡應用開發技術,學會應用所學理論知識來分析和解決實際問題,培養網絡技術研究與開發的基本能力以及創新精神.課程設計的主要任務通過本課程教學,要求學生熟悉TCP/IP協議工作機制、熟悉基于Socket的網絡通信程序的設計方法,熟練掌握至少一種編程語言及工具的使用。通過設計和調試有關程序,掌握一種網絡協議或算法的編程實現方法或具體應用,同時設計一個相對獨立的網絡應用程序。第二部分:滑動窗口協議仿真課程設計目的及要求程序按照滑動窗口協議實現端對端的數據傳送.包括協議的各種策略,如包丟失、停等應答、超時等都應有所仿真實現。顯示數據傳送過程中的各項具體數據;雙方幀的個數變化,幀序號,發送和接受速度,暫停或重傳提示等。增加其它附加創新功能。設計思想滑動窗口協議是TCP使用的一種流量控制方法。本次課程設計模擬仿真1比特滑動窗口協議,即停等協議.該協議規定,發送方每發送一幀后就要停下來,等待收到接收方正確接受的確定后再繼續發送下一幀。如果在規定的最大時延內沒有收到接收方的確認信號,則重新發送該幀。為了確認每次發送的幀是以前發過的還是新發送的,接收方需要發送方對每一幀加一個編號。由于停等協議規定只有一幀確認發送完成后才可以發送下一幀,因而只用一比特來編號就可以了。設計流程圖新數據或重發數據處理時間最大時延確認信號發送數據接收方發送方新數據或重發數據處理時間最大時延確認信號發送數據接收方發送方開發環境Window7,VC++關鍵代碼分析定義及初始化守法窗口typedefstruct/*接收窗口*/{?intr[MAXSIZE];?intfront; intrear;}wrece;voidInit(wsend*ws,wrece*wr)/*對發送和接收窗口進行初始化*/{ ws-〉front=ws->rear=0;?wr—>front=wr->rear=0;}說明發送窗口的發送情況intSEND(wsend*ws,wrece*wr,intframe){?if((ws->rear+1)%MAXSIZE==ws->front)return0;/*發送窗口已滿*/ if(ws->front==ws—〉rear)/*若窗口為空,則直接進入*/ {??ws—>s[ws—〉rear]。snum=frame;??ws->s[ws-〉rear]。timeout=1; ?ws—>rear=(ws—>rear+1)%MAXSIZE; wr—〉r[wr->rear]=frame;? wr-〉rear=(wr->rear+1)%MAXSIZE;??return1; }?else/*若窗口不為空,則判斷是否是可傳送的幀*/ {??if(frame==(ws-〉s[ws—>rear-1].snum)+1)?{? ws—>s[ws->rear].snum=frame; ?ws—>s[ws->rear].timeout=1; ?ws->rear=(ws->rear+1)%MAXSIZE;??wr—>r[wr->rear]=frame;??wr->rear=(wr->rear+1)%MAXSIZE; ?return1; } elseif(frame〈(ws->s[ws->rear—1]。snum)+1)printf(”該幀已發送!!\n");?elseif(frame〉(ws—>s[ws—〉rear-1]。snum)+1)printf("該幀不可發送!!\n");?}}說明接受窗口的接受情形intRECE(wrece*wr,intframe,intack[]){?if(wr->front==wr->rear)return0;/*接收窗口為空*/ else/*接收窗口接收幀號,并返回確認*/?{ if(wr->r[wr->front]==frame)??{?? wr—>front=(wr—〉front+1)%MAXSIZE; ?printf("第%d幀出接收窗口,向發送窗口返回確認。\n”,frame);? ?ack[i]=frame;? i++; ?}? elseprintf("該幀不是期望收到的幀,舍棄。\n");??return1; }}intACKNOWLEDGE(wsend*ws,intack[]){?intj; if(ws—>front==ws—〉rear)return0;/*發送窗口為空*/ if(ack[0]==ws-〉s[ws-〉front]。snum)/*發送窗口進行確認處理*/ {??ws->front=(ws->front+1)%MAXSIZE; ?for(j=0;j<i;j++) ? ack[j]=ack[j+1]; printf(”發送窗口收到確認,窗口向后移動.\n”); ?i-—;? return1; }?elseprintf(”無確認信息!!\n");}voidPRINT(wsend*ws,wrece*wr){?inta,b; a=ws->front;?b=wr—〉front; printf("發送窗口:"); while(a<ws—>rear)?{ ?printf("%3d",ws—〉s[a]); ?a++;?} printf(”\n");?printf(”接收窗口:”);?while(b〈wr—>rear)?{ printf(”%3d",wr-〉r[b]); b++; }?printf("\n");}接受錯誤要求重新發送main(){ intframe,a,flag=0;/*frame幀號,a指向窗口當前位置,flag是否有重發(0沒有,1有)*/?interr;?charend=’n’,ch,ACK;?intack[5];/*定義一個可存儲5個確認信息的*/ wsend*ws;?wrece*wr; ws=(wsend*)malloc(sizeof(wsend)); wr=(wrece*)malloc(sizeof(wrece));?Init(ws,wr);?printf("程序開始運行\n"); while(end!=’y’&&end!=’Y')?{? ? ?/*傳送處理*/??a=ws—>front;while(a<ws—>rear) { ??if(ws->s[a].timeout==6)? { ?ws-〉s[a].timeout=1; ? ?flag=1;? printf(”重發第%d幀\n",ws—〉s[a]);???} ?elsews-〉s[a]。timeout++; ? a++; } ?if(flag==0) {?? printf(”請輸入需傳送的幀號(0代表不輸入):”); ?scanf(”%d",&frame); ? if(frame!=0) { ???err=SEND(ws,wr,frame);? if(err==0)printf("發送窗口已滿!\n");? printf(”接收窗口期待接收到的幀號為:%d\n”,wr->r[wr—>front]);???? }? }仿真運行第三部分:網絡即時通訊程序課程設計目的及要求用戶登錄功能:客戶端登錄到聊天服務器,服務器管理所有登錄的客戶,并將客戶列表及狀態發送到各個客戶端顯示;用戶呼叫功能:用戶可通過客戶端向服務器發起呼叫請求;服務器搜索被呼叫的用戶,如果檢測到此用戶處于在線狀態,則通知此用戶的客戶端程序;當被叫用戶做出響應后,在主叫方和被叫方之間建立連接,雙方就可以聊天或進行媒體流傳輸;用戶消息也可以通過服務器轉發,實現一對一和多對多聊天;增加其它附加創新功能。設計思想實現網絡即時通訊的基本思想是由客戶端將信息發送到服務器端,然后由服務器端判斷將信息發往某個特定的用戶還是所有用戶。為實現用戶登錄功能,可以建立一個用戶信息的數據庫或文件,來實現用戶的登錄或注冊.用戶聊天功能的實現需要在用戶登錄進入聊天室時建立一個鏈接,該鏈接由服務器端監控,由此來實現用戶在線數量的控制和在線人數的顯示.當某一用戶發起對另一用戶的聊天請求時,由服務器端判斷該用戶是否在線,規定只能向在線用戶發送消息。若該用戶在線,則將發送用戶發送來的消息通過鏈接轉發到接收用戶的客戶端上,由客戶端顯示。如果發送用戶發送的消息是對所有人的,則將該消息轉發至所有人。其他創新功能包括了禁止某人發言或將某用戶踢出聊天室。禁止發言通過對其鏈接的屏蔽,踢出用戶則是由服務端斷開其鏈接,從而達到踢出某用戶的目的.設計流程圖退出登錄踢出禁言服務器客戶端建立鏈接并監聽進入聊天室驗證登錄服務器端客戶端退出登錄踢出禁言服務器客戶端建立鏈接并監聽進入聊天室驗證登錄服務器端客戶端開發環境Window7,SQLservice2005,VisualBasic關鍵代碼分析服務器設置聊天室最大人數并驗證登錄PrivateSubCommand1_Click()MaxChan=Val(Text1.Text)IfMaxChan<1OrMaxChan>100ThenText1.Text="”Text1.SetFocusElsefrmServer。ShowUnloadMeEndIfEndSubPrivateSubForm_Load()DimAsStringsys=fso.GetSpecialFolder(1)Iffso。(sys&"\Mswinsck.ocx")=TrueThenExitSubElseMsgBox(”Mswinsck。ocx不存在!準備安裝。.。..”)Iffso。("Mswinsck。ocx”)=TrueThenSetfil=fso。GetFile("Mswinsck。ocx")fil.Copy(sys&"\”)MsgBox(”Mswinsck.ock安裝成功!”)ElseMsgBox(”當前文件夾找不到Mswinsck.ocx,安裝失敗!”)EndIfEndIfEndSub客戶端登錄并向服務器驗證PrivateSubCommand1_Click()ServerIP=ReadServerIP("Setup.ini")userName=Trim(Text1。Text)IfuserName=””ThenMsgBox”姓名不能為空!"Text1。SetFocusExitSubEndIfLoadfrmClientCommand1.Enabled=FalseEndSubPrivateSubForm_Load()DimAsStringsys=fso.GetSpecialFolder(1)Iffso.(sys&"\Mswinsck.ocx")=TrueThenExitSubElseMsgBox("Mswinsck。ocx不存在!準備安裝..。。.”)Iffso.("Mswinsck.ocx”)=TrueThenSetfil=fso.GetFile("Mswinsck。ocx")fil。Copy(sys&"\")MsgBox("Mswinsck。ock安裝成功!")ElseMsgBox("當前文件夾找不到Mswinsck。ocx,安裝失敗!”)EndIfEndIf建立并監聽鏈接PublicFunctionReadServerIP(AsString)AsStringDimssAsStringcs=”"ss=””OpenForInputAs#1LineInput#1,ssClose#1ReadServerIP=Mid(ss,2,Len(ss)-2)EndFunction禁言與踢出功能的實現PrivateSubCommand1_Click()DimindexAsIntegerDimSAsStringDimrecUserAsStringS=Trim(Text2.Text)Text2.Text=""recUser=Combo1.TextIfrecUser=”所有人”ThenIfS=”SystemOrder:禁言"ThenFori=0ToMaxChan—1userState(i)=2NextEndIfElseindex=FindSckIndex(recUser)IfS="SystemOrder:禁言"ThenuserState(index)=2CallSendToOne(S,index)EndIfIfrecUser="所有人"ThenIfS="SystemOrder:踢出”ThenFori=0ToMaxChan-1userState(i)=3NextEndIfElseindex=FindSckIndex(recUser)IfS="SystemOrder:踢出”ThenuserState(index)=3CallSendToOne(S,index)EndIfS="對”&recUser&"說:"&SCallAddToText1(S)EndSubIfs="SystemOrder:踢出"ThensckClient.CloseMsgBox"很抱歉,你被管理員踢出!"UnloadMeExitSubEndIfIfs="SystemOrder:禁言"Thenn=1MsgBox”很抱歉,你被管理員禁言!"’UnloadMeExitSubEndIf私聊與公聊的實現PrivateSubcmdSend_Click()DimrecUserAsStringIfn<>1ThenrecUser=Combo1.TextIfCombo1.Text<>”所有人”ThenrecUser="<"&recUser&"〉"IfCheck1.Value=0OrCombo1.Text="所有人"ThensckClient.SendData”<”&userName&”>”&"對"&recUser&"說:"&txtSend.TextDoEventsElsesckClient.SendDataCombo1。Text&"038868SendToOne"&"<”&userName&"〉"&”悄悄對”&recUser&"說:"&txtSend.TextDoEventsEndIftxtSend。Text=”"ElseEndsub運行與調試第四部分:課程設計心得體會通過此次課程設計,實踐鞏固了《通信網原理》課程中學到的知識,并在實踐中練習了TCP/IP協議的使用.在滑動窗口協議的仿真中,由于能力不足,只能簡單的做了一比特滑動窗口協議即停等協議的仿真,而且沒有做到可視化界面,總體來說不盡人意。網絡即時通訊程序的編寫絕大部分由自己完成,僅在網上和書上參考查找了部分內容.此次課程設計不光是《通信網原理》課程的延伸,也是對以后網絡基礎的鋪墊。還有通過自己動手編寫程序,鍛煉了我的編程能力.第五部分:參考文獻吳功宜、吳英編著。《計算機網絡技術教程——自頂向下的分析與設計方法》.北京:機械工業出版社,2010謝希仁。《計算機網絡》(第4版).北京:電子工業出版社。劉韜,駱娟《VisualBasic數據庫通用模塊及電信系統開發》。機械工業出版社第六部分:附錄滑動窗口協議仿真#include”stdio.h"#include"malloc.h”#defineMAXSIZE10/*窗口大小,即隊列大小*/inti=0;/*全局變量,代表當前指向確認表的位置*/typedefstruct/*發送窗口每幀的數據*/{?intsnum; inttimeout;/*非0時代表發送計時,=6時表明超時*/}send;typedefstruct/*發送窗口*/{ sends[MAXSIZE]; intfront;?intrear;}wsend;typedefstruct/*接收窗口*/{ intr[MAXSIZE]; intfront; intrear;}wrece;voidInit(wsend*ws,wrece*wr)/*對發送和接收窗口進行初始化*/{ ws->front=ws->rear=0; wr-〉front=wr->rear=0;}intSEND(wsend*ws,wrece*wr,intframe){ if((ws->rear+1)%MAXSIZE==ws-〉front)return0;/*發送窗口已滿*/?if(ws—>front==ws->rear)/*若窗口為空,則直接進入*/?{? ws—〉s[ws—>rear].snum=frame;? ws->s[ws->rear].timeout=1; ws->rear=(ws—>rear+1)%MAXSIZE;? wr—〉r[wr->rear]=frame;? wr—>rear=(wr—〉rear+1)%MAXSIZE; return1; }?else/*若窗口不為空,則判斷是否是可傳送的幀*/?{ if(frame==(ws-〉s[ws—>rear-1].snum)+1) { ?ws—〉s[ws—>rear]。snum=frame;??ws—〉s[ws—〉rear].timeout=1;? ws->rear=(ws—〉rear+1)%MAXSIZE; ?wr->r[wr->rear]=frame; wr—>rear=(wr-〉rear+1)%MAXSIZE;??return1; }?elseif(frame〈(ws-〉s[ws—>rear-1].snum)+1)printf("該幀已發送!!\n");?elseif(frame〉(ws->s[ws—>rear-1].snum)+1)printf("該幀不可發送!!\n”);?}}intRECE(wrece*wr,intframe,intack[]){ if(wr-〉front==wr—>rear)return0;/*接收窗口為空*/?else/*接收窗口接收幀號,并返回確認*/ {? if(wr—〉r[wr-〉front]==frame) ?{? ?wr->front=(wr—〉front+1)%MAXSIZE;?? printf(”第%d幀出接收窗口,向發送窗口返回確認.\n”,frame);? ?ack[i]=frame;? i++;??}??elseprintf("該幀不是期望收到的幀,舍棄。\n”); ?return1; }}intACKNOWLEDGE(wsend*ws,intack[]){?intj; if(ws—>front==ws->rear)return0;/*發送窗口為空*/?if(ack[0]==ws—>s[ws-〉front].snum)/*發送窗口進行確認處理*/?{ ?ws-〉front=(ws-〉front+1)%MAXSIZE;? for(j=0;j<i;j++) ack[j]=ack[j+1]; printf("發送窗口收到確認,窗口向后移動。\n");??i--; ?return1;?}?elseprintf("無確認信息!!\n");}voidPRINT(wsend*ws,wrece*wr){ inta,b; a=ws-〉front;?b=wr—>front;?printf("發送窗口:”);?while(a<ws-〉rear) {? printf("%3d",ws—〉s[a]);? a++; } printf(”\n”); printf("接收窗口:");?while(b<wr->rear) {? printf("%3d”,wr—>r[b]); ?b++; } printf("\n");}main(){ intframe,a,flag=0;/*frame幀號,a指向窗口當前位置,flag是否有重發(0沒有,1有)*/ interr;?charend=’n’,ch,ACK;?intack[5];/*定義一個可存儲5個確認信息的*/ wsend*ws;?wrece*wr;?ws=(wsend*)malloc(sizeof(wsend)); wr=(wrece*)malloc(sizeof(wrece));?Init(ws,wr); printf(”程序開始運行\n"); while(end!='y'&&end!=’Y')?{ ? ? /*傳送處理*/ ?a=ws->front;while(a〈ws-〉rear)? { ??if(ws—〉s[a].timeout==6) ??{? ??ws-〉s[a].timeout=1; flag=1;??? printf(”重發第%d幀\n",ws->s[a]); ??} ?elsews-〉s[a].timeout++;? a++;??} ?if(flag==0) {?? printf(”請輸入需傳送的幀號(0代表不輸入):”);? ?scanf("%d”,&frame); if(frame!=0)?? { ? ?err=SEND(ws,wr,frame); ? if(err==0)printf("發送窗口已滿!\n");??? printf(”接收窗口期待接收到的幀號為:%d\n",wr-〉r[wr—>front]); ??? ?}? }? ch=getchar();? ? /*接收處理*/? printf("請輸入需接收的幀號(0代表不輸入):"); ?scanf(”%d",&frame);??if(frame!=0)err=RECE(wr,frame,ack); ?if(err==0)printf("接收窗口已空,沒有接受的幀!\n");??ch=getchar(); ? /*幀確認處理*/ printf(”是否進行確認?(y/n):”);? scanf(”%c”,&ACK);??if(ACK=='y’||ACK=='Y')??{???err=ACKNOWLEDGE(ws,ack); if(err==0)printf(”發送窗口已空!沒有需確認的幀!\n”); ?}? elseif(ACK=='n'||ACK==’N’)/*已發送幀的計時器加1*/ { ?printf(”不接收確認!\n”);?? a=ws—〉front; ? while(a<ws->rear)???{? ??ws->s[a].timeout++;?? a++; ? } } ch=getchar(); /*打印窗口幀號*/ ?PRINT(ws,wr); printf(”程序結束?y/n:");? scanf("%c",&end); }}網絡即時通訊程序服務器端1.1:登錄窗體DimfsoAsNewDimfilAsFilePrivateSubCommand1_Click()MaxChan=Val(Text1.Text)IfMaxChan〈1OrMaxChan>100ThenText1。Text=”"Text1。SetFocusElsefrmServer.ShowUnloadMeEndIfEndSubPrivateSubForm_Load()DimAsStringsys=fso.GetSpecialFolder(1)Iffso.(sys&"\Mswinsck。ocx")=TrueThenExitSubElseMsgBox(”Mswinsck.ocx不存在!準備安裝.。..。")Iffso.("Mswinsck。ocx”)=TrueThenSetfil=fso.GetFile("Mswinsck。ocx")fil.Copy(sys&"\")MsgBox("Mswinsck。ock安裝成功!")ElseMsgBox("當前文件夾找不到Mswinsck.ocx,安裝失敗!")EndIfEndIfEndSub1.2:聊天室服務器窗體DimHigAsLongDimconAsIntegerDimuserIP()AsStringDimuser()AsString'在線名單DimuserState()AsInteger’—1請求退出0離線1正常在線2只能看不能發言3正在被踢4客戶端非正常終止DimzxrsAsInteger’在線人數PrivateSubCommand1_Click()DimindexAsIntegerDimSAsStringDimrecUserAsStringS=Trim(Text2.Text)Text2。Text=”"recUser=Combo1.TextIfrecUser="所有人"ThenIfS="SystemOrder:禁言"ThenFori=0ToMaxChan-1userState(i)=2NextEndIfElseindex=FindSckIndex(recUser)IfS="SystemOrder:禁言"ThenuserState(index)=2CallSendToOne(S,index)EndIfIfrecUser=”所有人"ThenIfS=”SystemOrder:踢出"ThenFori=0ToMaxChan-1userState(i)=3NextEndIfElseindex=FindSckIndex(recUser)IfS="SystemOrder:踢出”ThenuserState(index)=3CallSendToOne(S,index)EndIfS="對"&recUser&"說:"&SCallAddToText1(S)EndSubPrivateSubForm_Load()ReDimuserState(MaxChan)ReDimuser(MaxChan)ReDimuserIP(MaxChan)DimiAsIntegerHig=24zxrs=0Fori=1ToMaxChan-1LoadsckServer(i)NextisckListen.LocalPort=1000sckListen.ListenCombo1。AddItem"所有人"Combo1.ListIndex=0EndSubPrivateSubHScroll1_Change()Text1.Left=—50—HScroll1。Value*10EndSubPrivateSubList1_Click()MsgBoxsckServer(FindSckIndex(List1。List(List1.ListIndex))).RemoteHostIP&""&sckServer(FindSckIndex(List1.List(List1.ListIndex))).RemotePortEndSubPrivateSubsckBusy_Close()sckBusy.CloseEndSubPrivateSubsckBusy_DataArrival(ByValbytesTotalAsLong)sckBusy.SendData"SystemOrder:服務器忙,請稍后再連接!"DoEventsEndSubPrivateSubsckListen_ConnectionRequest(ByValrequestIDAsLong)DimiAsInteger'決定由哪一Winsock接受請求Fori=0ToMaxChan—1IfsckServer(i).State=0ThenExitForEndIfNextiIfi=MaxChanThensckBusy.ClosesckBusy。AcceptrequestIDExitSubEndIfIfsckServer(i)。State=0ThensckServer(i)。AcceptrequestIDExitSubEndIf'如果所有Winsock都用完則由專門的“忙”Winsock接受請求,以免用戶要求得不到響應EndSubPrivateSubsckListen_Error(ByValNumberAsInteger,DescriptionAsString,ByValScodeAsLong,ByValSourceAsString,ByValHelpString,ByValHelpContextAsLong,CancelDisplayAsBoolean)sckListen。ClosesckListen.LocalPort=1000sckListen.ListenEndSubPrivateSubsckServer_Close(indexAsInteger)IfuserState(index)=2ThenuserState(index)=-1IfuserState(index)=1ThenuserState(index)=-1’客戶端請求退出CallStop_sckServer(index,userState(index))EndSubPrivateSubsckServer_DataArrival(indexAsInteger,ByValbytesTotalAsLong)DimSAsStringDimssAsStringDimiAsIntegerDimrecUserAsStringDimsenUserAsStringDimsenIPAsStringsckServer(index).GetDataS'接收信息到sIfuserState(index)=0Then'如果是剛進來,winsock尚未使用的話senUser=Trim(S)senIP=sckServer(index).RemoteHostIPIfInStr(1,senUser,"*")=1ThensenUser=Right(senUser,Len(senUser)—1)ElseIfcheckUserName(senUser)=1ThenCallSendToOne("SystemOrder:姓名重復,客戶端退出重進!",index)ExitSubEndIf'IfcheckUserIP(senIP)=1Then'CallSendToOne("SystemOrder:IP重復,客戶端退出重進!”,index)'ExitSub'EndIfEndIfS=”~~~~~~歡迎”&senUser&"進入聊天室!~~~~~~~"userState(index)=1'設置用戶狀態為正常在線user(index)=senUseruserIP(index)=senIPList1。AddItemuser(index)'加入到在線列表Combo1.AddItemuser(index)zxrs=zxrs+1ption=””&zxrs&”人在線"CallSendToAllExcept(”SystemOrder:addtolist"&user(index)&"038868",index)Fori=0ToList1.ListCount—1ss=ss&List1.List(i)&"038868”NextCallSendToOne(”SystemOrder:addtolist”&ss,index)EndIfIfInStr(1,S,"038868SendToOne”)=0ThenCallSendToAll(S)’廣播方式ElserecUser=Left(S,InStr(1,S,”038868SendToOne")-1)S=Right(S,Len(S)-Len(recUser)—Len("038868SendToOne"))CallSendToOne(S,FindSckIndex(recUser))Ifuser(index)<>recUserThenCallSendToOne(S,index)EndIf'將所發信息也寫入服務器CallAddToText1(S)EndSubPrivateSubsckServer_Error(indexAsInteger,ByValNumberAsInteger,DescriptionAsString,_ByValScodeAsLong,ByValSourceAsString,ByValHelpString,ByValHelpContextAs_Long,CancelDisplayAsBoolean)userState(index)=4'客戶端非正常終止CallStop_sckServer(index,userState(index))EndSub'利用winsock的State屬性給所有連接在服務器上的客戶發消息PrivateSubSendToAll(msgAsString)Fori=0ToMaxChan-1IfsckServer(i).State=7ThensckServer(i).SendDataTrim(msg)DoEventsEndIfNextiEndSub'給某個人發信息PrivateSubSendToOne(msgAsString,indexAsInteger)IfsckServer(index).State=7ThensckServer(index)。SendDatamsgDoEventsEndIfEndSubPrivateSubSendToAllExcept(msgAsString,indexAsInteger)Fori=0ToMaxChan-1IfsckServer(i).State=7Andindex〈>iThensckServer(i)。SendDataTrim(msg)DoEventsEndIfNextiEndSubPrivateSubAddToText1(SAsString)hang=Len(S)con=con+1Ifcon〉24ThenText1.Height=Text1。Height+5760/24VScroll1。Min=VScroll1。Min+1Text1.Top=Text1.Top-5760/24EndIfText1。Text=Text1。Text&S&Chr(13)&Chr(10)EndSubPrivateSubVScroll1_Change()ChangHeight=VScroll1。Value-HigText1.Top=Text1.Top+ChangHeight*(5760/24)Hig=VScroll1.ValueEndSubPrivateFunctionFindSckIndex(UserNameAsString)Fori=0ToMaxChan-1Ifuser(i)=UserNameThenExitForNextFindSckIndex=iEndFunctionPrivateFunctioncheckUserIP(IPAsString)AsIntegercheckUserIP=0Fori=0ToMaxChan—1IfuserIP(i)=IPThencheckUserIP=1ExitForEndIfNextEndFunctionPrivateFunctioncheckUserName(UserNameAsString)AsIntegercheckUserName=0Fori=0ToMaxChan—1Ifuser(i)=UserNameThencheckUserName=1ExitForEndIfNextEndFunctionPrivateSubStop_sckServer(indexAsInteger,StateAsInteger)'State=—1正常終止'State>0非正常終止DimSAsStringsckServer(index).CloseIfuserState(index)<>0Thenzxrs=zxrs—1’在線人數減一ption=""&zxrs&”人在線”S="~~~~~~"&user(index)&"未知原因被終止!~~~~~~"IfState=—1ThenS="~~~~~~”&user(index)&"退出聊天室~~~~~~”IfState=3ThenS="~~~~~~"&user(index)&"被管理員踢出聊天室~~~~~~”IfState=4ThenS=”~~~~~~"&user(index)&"非正常退出!~~~~~~"CallSendToAll(S)DoEventsCallSendToAll("SystemOrder:removefromlist”&user(index))Fori=0ToList1.ListCount-1IfList1.List(i)=user(index)ThenExitForNextList1。RemoveItemi’從在線名單上刪除退出者Combo1。RemoveItemi+1Combo1.ListIndex=0user(index)=""'清除退出者姓名記錄userIP(index)="”'清除退出者IP記錄userState(index)=0’設置用戶狀態為離線CallAddToText1(S)EndIfEndSub1.3:模塊PublicMaxChanAsInteger客戶端2.1:登錄窗體DimfsoAsNewDimfilAsFilePrivateSubCommand1_Click()ServerIP=ReadServerIP("Setup.ini”)userName=Trim(Text1.Text)IfuserName="”ThenMsgBox"姓名不能為空!"Text1。SetFocusExitSubEndIfLoadfrmClientCommand1。Enabled=FalseEndSubPrivateSubForm_Load()DimAsStringsys=fso。GetSpecialFolder(1)Iffso.(sys&”\Mswinsck。ocx")=TrueThenExitSubElseMsgBox(”Mswinsck。ocx不存在!準備安裝.。。。.")Iffso.(”Mswinsck.ocx")=TrueThenSetfil=fso.GetFile(”Mswinsck.ocx”)fil。Copy(sys&”\")MsgBox(”Mswinsck.ock安裝成功!”)ElseMsgBox(”當前文件夾找不到Mswinsck。ocx,安裝失敗!")EndIfEndIfEndSubPrivateSubImage1_Click()EndSubPrivateSubSetIP_Click()frmSetIP.ShowEndSub2。2:服務器IP設置窗體PrivateSubcmdOK_Click()WriteServerIP(”Setup.ini")UnloadMeEndSubPrivateSubCommand1_Click()UnloadMeEndSubPrivateFunctionWriteServerIP(AsString)AsStringDimssAsStringOpenForOutputAs#1Write#1,Text1。TextClose#1EndFunctionPrivateSubForm_Load()Text1。Text=ReadServerIP("Setup。ini")EndSub2。3:客戶端聊天室窗體DimnAsIntegerDimHigAsLongDimconAsIntegerPrivateSubConnectServer()OnErrorGoToErrorProsckClient.ConnectExitSubErrorPro:MsgBox”服務器未開或網絡出錯!"EndEndSubPrivateSubcmdSend_Click()DimrecUserAsStringIfn<>1ThenrecUser=Combo1。TextIfCombo1。Text〈>”所有人”ThenrecUser="<"&recUser&”>”IfCheck1.Value=0OrCombo1。Text="所有人”ThensckClient.SendData"<"&userName&"〉"&"對"&recUser&"說:”&txtSend.TextDoEventsElsesckClient.SendDataCombo1.Text&"038868SendToOne"&"〈"&userName&"〉"&”悄悄對"&recUser&"說:"&txtSend。TextDoEventsEndIftxtSend.Text=""ElsetxtSend。Text="”MsgBox”很抱歉,你被管理員禁言!”EndIfEndSubPrivateSubcmdCls_Click()Text1。Text=""Text1.Height=4680Text1.Top=-50VScroll1。Max=19VScroll1。Min=19Hig=19con=0EndSubPrivateSubcmdExit_Click()UnloadMeEndSubPrivateSubCommand1_Click()sckClient.SendDataText2.TextEndSubPrivateSubForm_Load()ption=userNameHig=19'RemoteComputerName為服務器端的計算機名或IP地址。Msgnum=0connecting_Time=0'連接用去的秒數connect_OutTime=3'連接超時時限為3秒sckClient。RemoteHost=ServerIPsckClient.RemotePort=1000CallConnectServerCombo1.AddItem"所有人"Combo1.ListIndex=0EndSubPrivateSubForm_Unload(CancelAsInteger)sckClient。CloseEndSubPrivateSubHScroll1_Change()Text1.Left=—50-HScroll1.Value*10EndSubPrivateSubsckClient_Close()MsgBox”服務器通道已關閉!",0+16+0,"聊天室客戶端”EndEndSubPrivateSubsckClient_Connect()sckClient.SendDatauserNameIfInStr(1,userName,"*”)=1ThenuserName=Right(userName,Len(userName)-1)EndIfEndSubPrivateSubsckClient_DataArrival(ByValbytesTotalAsLong)DimsAsStringMsgnum=Msgnum+1sckClient.GetDatas'MsgBoxsIfInStr(1,s,"SystemOrder:")=1ThenIfs=”SystemOrder:服務器忙,請稍后再連接!”ThensckClient.CloseMsgBox”聊天室人滿為患,請稍后再進!”mand1。Enabled=TrueUnloadMeExitSubEndIfIfs=”SystemOrder:IP重復,客戶端退出重進!”ThensckClient.CloseMsgBox"您不能使用同一個IP地址重復登錄!"mand1。Enabled=TrueUnloadMeExitSubEndIfIfs=”SystemOrder:姓名重復,客戶端退出重進!"ThensckClient.CloseMsgBox"很抱歉,這個姓名有人正在使用,請換一個再試!”mand1。Enabled=TrueUnloadMeExitSubEndIfIfs=”SystemOrder:踢出”ThensckClient.CloseMsgBox"很抱歉,你被管理員踢出!"UnloadMeExitSubEndIfIfs="SystemOrder:禁言"Thenn=1MsgBox”很抱歉,你被管理員禁言!”’UnloadMeExitSubEndIfIfInStr(1,s,”SystemOrder:addtolist")=1Thens=Right(s,Len(s)-21)'MsgBoxsCallGetUsersName(s)

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論