版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、<p> VC++面向?qū)ο笳n程設(shè)計(jì)報(bào)告</p><p> 院(系): 計(jì)算機(jī)系 </p><p> 專業(yè): 計(jì)算機(jī)網(wǎng)絡(luò) </p><p> 題目: 局域網(wǎng)聊天程序 </p><p><b&g
2、t; 目錄</b></p><p><b> 一 需求分析3</b></p><p> 1.1 客戶機(jī)端3</p><p> 1.2 服務(wù)器端3</p><p><b> 二 設(shè)計(jì)內(nèi)容4</b></p><p> 2.1 程序整體結(jié)構(gòu)4<
3、;/p><p> 2.2 各部分子模塊功能5</p><p> 2.3 各子模塊代碼編寫6</p><p><b> 三 調(diào)試分析8</b></p><p> 3.1 實(shí)際完成情況8</p><p> 3.2 出現(xiàn)的問(wèn)題及解決方案8</p><p> 3.
4、3 可以改進(jìn)的地方9</p><p> 3.4 可以擴(kuò)充的功能10</p><p><b> 四 用戶手冊(cè)11</b></p><p> 4.1 程序主界面11</p><p> 4.2 獲取本地信息11</p><p> 4.3 發(fā)送信息12</p><
5、p> 4.4 接收信息12</p><p> 4.5 總體演示12</p><p><b> 五 設(shè)計(jì)總結(jié)13</b></p><p><b> 六 參考文獻(xiàn)14</b></p><p><b> 七 附錄15</b></p><p
6、><b> 需求分析</b></p><p> 此次開發(fā)的網(wǎng)絡(luò)聊天工具可作為個(gè)人的交流工具使用,通信的安全性不是很高,但要求信息的響應(yīng)速度要較快,讓用戶充分享受到網(wǎng)絡(luò)即時(shí)消息的方便和快捷。本聊天工具由服務(wù)器端程序和客戶端程序兩部分組成,整體采用C++平臺(tái)開發(fā),沒(méi)有使用管理數(shù)據(jù)庫(kù)。服務(wù)器和與客戶端都包含與用戶的交互式界面,它有必要的界面的按鈕,向用戶提供網(wǎng)絡(luò)即時(shí)消息的功能。本聊天需要
7、包含如下本功能:</p><p><b> 客戶機(jī)端</b></p><p><b> 獲取本地IP地址</b></p><p><b> 獲取本地通信端口</b></p><p><b> 獲取遠(yuǎn)程IP地址</b></p><
8、p><b> 獲取本地主機(jī)名</b></p><p> 獲取從服務(wù)器端發(fā)送過(guò)來(lái)的信息</p><p> 給服務(wù)器發(fā)送用戶自定義的數(shù)據(jù)</p><p><b> 服務(wù)器端</b></p><p><b> 獲取本地IP地址</b></p><p
9、><b> 獲取本地通信端口</b></p><p><b> 獲取遠(yuǎn)程IP地址</b></p><p><b> 獲取本地主機(jī)名</b></p><p> 獲取從服務(wù)器端發(fā)送過(guò)來(lái)的信息</p><p> 向客戶機(jī)發(fā)送用戶自定義的數(shù)據(jù)</p>&l
10、t;p><b> 設(shè)計(jì)內(nèi)容</b></p><p><b> 程序整體結(jié)構(gòu)</b></p><p><b> 各部分子模塊功能</b></p><p><b> 各子模塊代碼編寫</b></p><p> WM_INITDIALOG模塊&l
11、t;/p><p> switch(UMsg)</p><p><b> {</b></p><p> case WM_INITDIALOG:</p><p> CLIENT.INIT_MYSOCKET(hwndDlg);</p><p> ==========================
12、=================</p><p> void MYSOCKET::INIT_MYSOCKET(HWND &hwndDlg)</p><p> { WSAStartup(0x0101, &wsaData);</p><p> udp_sd=socket(AF_INET, SOCK_DGRAM, 0);</p>
13、<p> bind(udp_sd, (LPSOCKADDR)&Local_PC, sizeof(Local_PC));</p><p> WSAAsyncSelect(udp_sd, hwndDlg, WM_USER+1, FD_READ);</p><p><b> }</b></p><p><b> I
14、DOK模塊</b></p><p> switch(LOWORD(wParam))</p><p><b> {</b></p><p> case IDOK:</p><p> CLIENT.MYSOCK_SEND(hwndDlg);</p><p><b> b
15、reak;</b></p><p> ===========================================</p><p> void MYSOCKET::MYSOCK_SEND(HWND &hwndDlg)</p><p> { GetDlgItemText(hwndDlg, IDC_SEND, Buffer, si
16、zeof(Buffer));</p><p> sendto(udp_sd, Buffer, strlen(Buffer), 0, (struct sockaddr *)&Remote_PC, len);</p><p><b> } </b></p><p> IDCANCEL模塊</p><p> c
17、ase IDCANCEL:</p><p> CLIENT.END_MYSOCKET(hwndDlg);</p><p> EndDialog(hwndDlg, 0);</p><p><b> break;</b></p><p> =======================================
18、====</p><p> void END_MYSOCKET(HWND &hwndDlg)</p><p> { WSAAsyncSelect(udp_sd, hwndDlg, 0, 0);</p><p> closesocket(udp_sd);</p><p> WSACleanup();</p>
19、<p><b> } </b></p><p><b> FD_READ模塊</b></p><p> case WM_USER+1:</p><p> switch(LOWORD(lParam))</p><p><b> {</b></p>
20、<p> case FD_READ:</p><p> CLIENT.MYSOCK_RECV(hwndDlg);</p><p><b> break;</b></p><p><b> }</b></p><p> ==============================
21、=============</p><p> void MYSOCKET::MYSOCK_RECV(HWND &hwndDlg)</p><p><b> {</b></p><p> recv(udp_sd, Buffer, sizeof(Buffer), 0);</p><p> SetDlgItem
22、Text(hwndDlg, IDC_RECV, Buffer);</p><p><b> }</b></p><p><b> 調(diào)試分析</b></p><p><b> 實(shí)際完成情況</b></p><p> 經(jīng)過(guò)幾天的學(xué)習(xí)及調(diào)試,該“局域網(wǎng)聊天程序”僅僅能實(shí)現(xiàn)點(diǎn)對(duì)
23、點(diǎn)通信,不能實(shí)現(xiàn)一對(duì)多、多對(duì)多、多對(duì)一等通信模式,也就是說(shuō),只能開啟一個(gè)客戶機(jī)和一個(gè)服務(wù)器,若有多個(gè)程序副本在運(yùn)行,則可能導(dǎo)致接收以及發(fā)送數(shù)據(jù)的混亂。</p><p> 用戶在輸入數(shù)據(jù)的時(shí)候不能包含換行符號(hào),即只能輸入一行信息。</p><p> 用戶在接受數(shù)據(jù)的時(shí)候,不能判定它是來(lái)自哪臺(tái)主機(jī)。</p><p> 服務(wù)器端不能自動(dòng)發(fā)現(xiàn)上線的客戶端,同樣客戶端也
24、不能自動(dòng)發(fā)現(xiàn)上線的服務(wù)器端,兩者都是在假設(shè)對(duì)方在線的前提下發(fā)送數(shù)據(jù)的,這是因?yàn)樵摗熬钟蚓W(wǎng)聊天程序”是基于UDP協(xié)議編寫的,它是無(wú)連接的協(xié)議。</p><p> 出現(xiàn)的問(wèn)題及解決方案</p><p><b> C++類的封裝性</b></p><p> 封裝就是把對(duì)象的屬性和操作結(jié)合成一個(gè)獨(dú)立的系統(tǒng)單位,并盡可能隱蔽對(duì)象的內(nèi)部細(xì)節(jié)。通過(guò)對(duì)抽
25、象結(jié)果進(jìn)行封裝,將一部分行為作為外部訪問(wèn)的接口與外部發(fā)送聯(lián)系,而將數(shù)據(jù)和其他行為進(jìn)行有效隱藏,就可以達(dá)到對(duì)數(shù)據(jù)訪問(wèn)權(quán)限的合理控制。通過(guò)這種有效隱藏和合理控制,就可以增強(qiáng)數(shù)據(jù)的安全性,減輕開發(fā)軟件系統(tǒng)的難度。在類中,封裝是通過(guò)存取權(quán)限實(shí)現(xiàn)的。</p><p> 雖然封裝性是C++的一個(gè)重要特點(diǎn),但在編寫“局域網(wǎng)聊天程序”的時(shí)候給我造成了很大的阻礙。</p><p> 起初我是把負(fù)責(zé)“接收
26、”、“發(fā)送”數(shù)據(jù)的緩沖變量“Buffer”封裝在類中(私有成員),但操作Buffer的函數(shù)(如GetDlgItemText、 SetDlgItemText)都是在類外訪問(wèn)Buffer變量,開始以為通過(guò)return語(yǔ)句把指針傳送到對(duì)象外就能操作對(duì)象里面的Buffer變量,但經(jīng)過(guò)一段時(shí)間的測(cè)試,程序不能正常運(yùn)行。</p><p> 所以我改變了類的封裝方式,不但把Buffer變量封裝在類里面,而且把操作Buffer
27、變量的函數(shù)也封裝為類中的某些成員函數(shù),這樣就解決了C++類的封裝特性給我?guī)?lái)的問(wèn)題。</p><p><b> 對(duì)象是自動(dòng)變量</b></p><p> 局部變量,如不作專門說(shuō)明為靜態(tài)變量,都是動(dòng)態(tài)分配存儲(chǔ)空間,存儲(chǔ)在動(dòng)態(tài)存儲(chǔ)區(qū)中。這種變量叫自動(dòng)變量。這種變量只在定義它們的時(shí)候才創(chuàng)建,在定義它們的函數(shù)返回時(shí)系統(tǒng)回收變量所占存儲(chǔ)空間。對(duì)這些變量存儲(chǔ)空間的分配和回收是
28、由系統(tǒng)自動(dòng)完成的,所以也叫自動(dòng)變量。一般情況下,不作專門說(shuō)明的局部變量,均是自動(dòng)變量。</p><p> BOOL DialogProc(HWND hwndDlg,UINT UMsg,WPARAM wParsam,LPARAM lParam)</p><p><b> {</b></p><p> static MYSOCKET CLI
29、ENT(TEXT("127.0.0.1"), 4321, TEXT("127.0.0.1"), 6321);</p><p> switch(UMsg)</p><p><b> {</b></p><p> case WM_INITDIALOG: </p><p> CL
30、IENT.INIT_MYSOCKET(hwndDlg); //初始化套接字</p><p> ……………………………….</p><p> DialogProc函數(shù)是系統(tǒng)指定的對(duì)話框消息處理回調(diào)函數(shù),它是被系統(tǒng)自動(dòng)地根據(jù)用戶消息調(diào)用。而且發(fā)送給該函數(shù)的消息“WM_INITDIALOG”只有在初始化對(duì)話框時(shí)才被調(diào)用,由于局部變量默認(rèn)是自動(dòng)變量,所以由MYSOCKET類構(gòu)造的CLIENT對(duì)
31、象在每次系統(tǒng)回調(diào)該函數(shù)的時(shí)候,都會(huì)被初始化一遍,而這種操作破壞了套接字與本地信息的綁定,因此服務(wù)器端于客戶機(jī)端程序不能正常通信。</p><p> 解決這個(gè)問(wèn)題的方法就是使用static操作符使變量變成靜態(tài)值,使CLIENT對(duì)象在函數(shù)在多次被調(diào)用時(shí),能夠維持它的原始值。</p><p><b> 即把語(yǔ)句</b></p><p> MYS
32、OCKET CLIENT(TEXT("127.0.0.1"), 4321, TEXT("127.0.0.1"), 6321);</p><p><b> 改變?yōu)檎Z(yǔ)句</b></p><p> static MYSOCKET CLIENT(TEXT("127.0.0.1"), 4321, TEXT(&quo
33、t;127.0.0.1"), 6321);</p><p><b> 程序正常運(yùn)行</b></p><p><b> 端口沖突</b></p><p> 程序給服務(wù)器端分配的的端口號(hào)是5000, 給客戶機(jī)端分配的端口號(hào)是4000。程序一直運(yùn)行的很正常,但偶然的一次測(cè)試發(fā)現(xiàn)程序間不能正常通信,經(jīng)過(guò)反復(fù)的調(diào)試、
34、測(cè)試并沒(méi)有發(fā)現(xiàn)代碼中存在什么問(wèn)題。我試著改了改端口號(hào)服務(wù)器端:6321;客戶機(jī)端:4321。測(cè)試通過(guò)了。</p><p><b> 可以改進(jìn)的地方</b></p><p><b> 用戶界面</b></p><p> 用VC++開發(fā)的界面生硬、死板,并不友好,若能使用一些開發(fā)程序皮膚的庫(kù)文件,使用戶界面更加友好。&l
35、t;/p><p><b> 可以擴(kuò)充的功能</b></p><p><b> 多用戶聊天</b></p><p> 本程序的邏輯拓?fù)淇梢詮幕赨DP無(wú)連接協(xié)議的“點(diǎn)對(duì)點(diǎn)”拓?fù)?,轉(zhuǎn)化為基于TCP面向連接的“星型”拓?fù)?,以?shí)現(xiàn)多用戶之間的回話。</p><p> 若能采用TCP協(xié)議,用戶間的通信時(shí)通
36、過(guò)服務(wù)器的轉(zhuǎn)發(fā)功能實(shí)現(xiàn)的,服務(wù)器端程序不修改接收的的信息,只充當(dāng)“數(shù)據(jù)轉(zhuǎn)發(fā)角色”,把數(shù)據(jù)按照用戶想要傳送的目的地發(fā)送到目的。假設(shè)客戶機(jī)A想要把數(shù)據(jù)發(fā)送給客戶機(jī)B,客戶機(jī)A先把數(shù)據(jù)發(fā)送給服務(wù)器端,然后服務(wù)器將數(shù)據(jù)轉(zhuǎn)發(fā)給客戶機(jī)B,這樣對(duì)客戶機(jī)A而言,服務(wù)器端是透明的,好像是客戶機(jī)直接在跟客戶機(jī)B通信一樣。</p><p> 具體的拓?fù)淙缦聢D所示:</p><p><b> 自動(dòng)發(fā)
37、現(xiàn)功能</b></p><p> 假設(shè)服務(wù)器端程序在線,當(dāng)客戶端程序上線的時(shí)候,服務(wù)器端能夠自動(dòng)偵測(cè)到客戶機(jī)端上線,并獲取客戶機(jī)端的用戶名、IP地址、通信端口號(hào)等必要通信信息,并記錄在自己的數(shù)據(jù)庫(kù)中登記。</p><p><b> 文件發(fā)送共更能</b></p><p> 在聊天功能(即發(fā)送字符信息)成功實(shí)現(xiàn)的前提下,可以再加
38、入文件傳送功能,使這個(gè)“局域網(wǎng)聊天程序”的功能更加強(qiáng)大。</p><p><b> 用戶手冊(cè)</b></p><p><b> 程序主界面</b></p><p> 雖然本程序是基于客戶機(jī)/服務(wù)器(C/S)模式的通信,但兩者的用戶界面是一致的,所以在使用上不會(huì)給用戶帶來(lái)困難。</p><p>
39、 服務(wù)器端、客戶端都包含一個(gè)接受信息的控件(IDC_RECV)、一個(gè)用于發(fā)送信息的控件(IDC_SEND)、一個(gè)發(fā)送按鈕(IDOK)、部分靜態(tài)文本(IDC_STATIC)、部分本機(jī)信息控件(本地主機(jī)名(IDC_HOST)、本地IP地址(IDC_IP)、本地端口號(hào)(IDC_PORT)、遠(yuǎn)程IP地址(IDC_IP_REMOTE))。</p><p><b> 獲取本地信息</b></p
40、><p> 服務(wù)器端和客戶機(jī)端的信息是自動(dòng)獲取的,不需要用戶干預(yù)。它將自動(dòng)獲取本地主機(jī)名、本地IP地址、本地端口號(hào)、遠(yuǎn)程通信IP地址。</p><p> 下面是在不同計(jì)算機(jī)上運(yùn)行客戶機(jī)端的本地信息截圖。</p><p><b> 發(fā)送信息</b></p><p> 只要在“發(fā)送:”下面的控件窗口中填入您想要發(fā)送的信息
41、,然后按“發(fā)送”按鈕,即可發(fā)送到遠(yuǎn)程計(jì)算機(jī)。</p><p><b> 接收信息</b></p><p> 客戶端、服務(wù)器端接收的信息,都會(huì)顯示在“接收”控件中。</p><p><b> 總體演示</b></p><p> 同時(shí)運(yùn)行UDP Client和UDP Server。</p&
42、gt;<p> 在Server端發(fā)送“Hello, I’M Server!”,在Client端發(fā)送“Hello, IM Client”。</p><p> 在程序、網(wǎng)絡(luò)正常的情況下,Server端會(huì)接收到Client端發(fā)送的信息“Hello, IM Client”;同樣,Client端會(huì)接收到Server端發(fā)送的信息“Hello, I’M Server!”。</p><p&g
43、t;<b> 設(shè)計(jì)總結(jié)</b></p><p> 經(jīng)過(guò)兩個(gè)兩個(gè)星期的實(shí)踐學(xué)習(xí),使我對(duì)C++語(yǔ)言、WINDOWS編程、WINDOWS SOCKET編程有了更進(jìn)一步的認(rèn)識(shí)和了解,要想學(xué)好它重要在實(shí)踐,要通過(guò)不斷的上機(jī)操作才能更好地學(xué)習(xí)它,通過(guò)實(shí)踐,我也發(fā)現(xiàn)我的好多不足之處,首先是自己在指法上還不行,經(jīng)常按錯(cuò)字母,通過(guò)學(xué)習(xí)也有所改進(jìn);再有對(duì)SOCKET API中的一些標(biāo)準(zhǔn)函數(shù)庫(kù)不太了解,還有對(duì)
44、函數(shù)調(diào)用的正確使用不夠熟悉,還有對(duì)C++語(yǔ)言中經(jīng)常出現(xiàn)的錯(cuò)誤也不了解,通過(guò)實(shí)踐,使我在這幾個(gè)方面的認(rèn)識(shí)有所提高。</p><p> 通過(guò)實(shí)踐的學(xué)習(xí),我認(rèn)識(shí)到學(xué)好計(jì)算機(jī)要重視實(shí)踐操作,不僅僅是學(xué)習(xí)C++語(yǔ)言,還是WINDOWS編程,以及其它的計(jì)算機(jī)方面的知識(shí)都要重在實(shí)踐,所以以后再學(xué)習(xí)過(guò)程中,我會(huì)更加注重實(shí)踐操作,使自己更好地學(xué)好計(jì)算機(jī)。</p><p> 尤其是在使用SDK編寫基于對(duì)話
45、框的程序時(shí),接觸了全新的WINDOWS的“消息處理”機(jī)制。在參考了眾多資料后,成功調(diào)試了“局域網(wǎng)聊天程序”的用戶界面,這為后期編寫SOCKET核心代碼提供了基礎(chǔ)。編寫通信部分核心代碼時(shí),也加深了對(duì)“套接字”、“綁定”、“動(dòng)態(tài)鏈接庫(kù)”、“端口”等屬于的理解。</p><p> 由于本次設(shè)計(jì)接觸到了兩個(gè)全新的領(lǐng)域,一是網(wǎng)絡(luò)通信程序的編寫,另一個(gè)是C++面向?qū)ο蟪绦虻木帉?,為了在開發(fā)后期更好的分離錯(cuò)誤的出處,我先是用
46、C語(yǔ)言獨(dú)立編寫了網(wǎng)絡(luò)通信部分、用戶界面部分,然后再由C++將其封裝為類,但中間的調(diào)試花費(fèi)了我大量的時(shí)間,就是因?yàn)闆](méi)有充分理解C++類的封裝性與C面向過(guò)程程序設(shè)計(jì)的異同。所以本次開發(fā)使我更好的認(rèn)識(shí)了C++、C、Windows以及網(wǎng)絡(luò)通信的知識(shí)。</p><p> 通過(guò)分析、設(shè)計(jì)、編碼、調(diào)試等各環(huán)節(jié)的訓(xùn)練,深刻理解、C++程序設(shè)計(jì)技術(shù),掌握分析、解決實(shí)際問(wèn)題的能力。綜合運(yùn)用所學(xué)知識(shí),上機(jī)解決一些與實(shí)際應(yīng)用結(jié)合緊密的
47、、規(guī)模較大的問(wèn)題,逐步掌握軟件開發(fā)的基本思想、方法和實(shí)現(xiàn)步驟,提高實(shí)際應(yīng)用水平。</p><p> 這次課程設(shè)計(jì)基本上含蓋了本學(xué)期學(xué)習(xí)到的C++語(yǔ)言知識(shí)點(diǎn),課設(shè)題目要求不僅要求對(duì)課本知識(shí)有較深刻的了解,同時(shí)要求程序設(shè)計(jì)者有較強(qiáng)的動(dòng)手能力以及自學(xué)能力。這次課設(shè)使我了解我編程思想和編程技巧,也認(rèn)識(shí)了軟件生命周期的各個(gè)環(huán)境,包括構(gòu)思、設(shè)計(jì)、編寫、調(diào)試、發(fā)布、文檔化、維護(hù)和修訂。編程的風(fēng)格也很重要,程序有了良好的編程風(fēng)
48、格,有良好的程序注釋,會(huì)在后期調(diào)試程序、程序排錯(cuò)過(guò)程中獲益的;若只關(guān)心程序運(yùn)行的結(jié)果,而對(duì)程序代碼的結(jié)構(gòu)的良好絲毫不在意,是非常不可取的,如果我們希望將來(lái)從事編程工作,在這一點(diǎn)上該引起足夠的重視。這是嚴(yán)謹(jǐn)?shù)膽B(tài)度,很重要!</p><p><b> 參考文獻(xiàn)</b></p><p> Jeffrey Richter,Christophe Nasarre. Windo
49、ws核心編程(第五版). 北京:清華大學(xué)出版社. 2008.9</p><p> Charles Petzold. Windows程序設(shè)計(jì)(第五版). 北京:北京大學(xué)出版社. 1999.11</p><p> Kenneth A.Reek. C和指針。 北京:人名郵電出版社. 2008.4</p><p> 李蘭,任鳳華. C++面向?qū)ο蟪绦蛟O(shè)計(jì). 西安:西安
50、電子科技大學(xué)出版社. 2010.9</p><p> W.Richard Stevens. TCP/IP詳解 卷1:協(xié)議. 北京:機(jī)械工業(yè)出版社. 2000.4</p><p> 鄭莉.C++語(yǔ)言程序設(shè)計(jì)(第3版).北京:清華大學(xué)出版社,2005.7</p><p> 錢能.C++程序設(shè)計(jì)教程(第2版).北京:清華大學(xué)出版社,2005.8</p>
51、<p> 譚浩強(qiáng). C++程序設(shè)計(jì). 北京:清華大學(xué)出版社. 2001</p><p><b> 附錄</b></p><p> /////////////////////////////////////////////////////////////////////////</p><p> // 服務(wù)器端與客戶機(jī)端所使
52、用的類</p><p> // COMMON.H</p><p> class MYSOCKET</p><p><b> {</b></p><p><b> public:</b></p><p><b> /*</b></p>
53、;<p> **MYSOCKET類構(gòu)造函數(shù)</p><p> ** 1.保存通信端口到成員變量</p><p> ** A.本地:Local_Port_Num</p><p> ** B.遠(yuǎn)程:Remote_Port_Num</p><p><b> **</b></p>&
54、lt;p> ** 2.設(shè)置通信地址及端口</p><p> ** A.本地:127.0.0.1:local_port</p><p> ** B.遠(yuǎn)程:127.0.0.1:remote_port</p><p><b> **</b></p><p> ** 3.獲取"struct so
55、ckaddr"類型長(zhǎng)度</p><p><b> */</b></p><p> MYSOCKET(TCHAR *Local_IP,</p><p> WORD local_port,</p><p> TCHAR *Remote_IP,</p><p> WORD remot
56、e_port)</p><p><b> {</b></p><p> Local_Port_Num=local_port;</p><p> Remote_Port_Num=remote_port;</p><p> memset(&Local_PC, 0, sizeof(Local_PC));<
57、/p><p> Local_PC.sin_family=AF_INET;</p><p> Local_PC.sin_addr.s_addr=inet_addr(Local_IP);</p><p> Local_PC.sin_port=htons(local_port);</p><p> memset(&Remote_PC,
58、0, sizeof(Remote_PC));</p><p> Remote_PC.sin_family=AF_INET;</p><p> Remote_PC.sin_addr.s_addr=inet_addr(Remote_IP);</p><p> Remote_PC.sin_port=htons(remote_port);</p><
59、;p> len=sizeof(struct sockaddr_in);</p><p><b> }</b></p><p><b> /*</b></p><p><b> **初始化套接字</b></p><p> ** 1.用WSAStartup函數(shù)啟動(dòng)網(wǎng)
60、絡(luò)動(dòng)態(tài)鏈接庫(kù)</p><p> ** 2.用socket函數(shù)生成UDP套接字</p><p> ** 3.用bind函數(shù)將UDP套接字與本機(jī)綁定</p><p> ** 4.用WSAAsyncSelect函數(shù)注冊(cè)網(wǎng)絡(luò)異步選擇事件消息</p><p><b> */</b></p><p>
61、 void INIT_MYSOCKET(HWND &hwndDlg)</p><p><b> {</b></p><p> WSAStartup(0x0101, &wsaData);</p><p> udp_sd=socket(AF_INET, SOCK_DGRAM, 0);</p><p>
62、 bind(udp_sd, (LPSOCKADDR)&Local_PC, sizeof(Local_PC));</p><p> WSAAsyncSelect(udp_sd, hwndDlg, WM_USER+1, FD_READ);</p><p><b> }</b></p><p><b> /*</b&g
63、t;</p><p><b> **發(fā)送消息</b></p><p> ** 1.用GetDlgItemText函數(shù)從控件IDC_SEND獲取用戶即將發(fā)送的數(shù)據(jù)</p><p> ** 2.用sendto函數(shù)向目的主機(jī)發(fā)送UDP數(shù)據(jù)報(bào)</p><p><b> */</b></p&
64、gt;<p> void MYSOCK_SEND(HWND &hwndDlg)</p><p><b> {</b></p><p> GetDlgItemText(hwndDlg, IDC_SEND, Buffer, sizeof(Buffer));</p><p> sendto(udp_sd, Buffer,
65、 strlen(Buffer), 0, (struct sockaddr *)&Remote_PC, len);</p><p><b> }</b></p><p><b> /*</b></p><p><b> **接收消息</b></p><p> **
66、 1.用recv函數(shù)接受數(shù)據(jù),并存儲(chǔ)于Buffer緩沖區(qū)</p><p> ** 2.用SetDlgItemText函數(shù)設(shè)置控件IDC_RECV,使信息顯示在屏幕上</p><p><b> */</b></p><p> void MYSOCK_RECV(HWND &hwndDlg)</p><p>
67、<b> {</b></p><p> recv(udp_sd, Buffer, sizeof(Buffer), 0);</p><p> SetDlgItemText(hwndDlg, IDC_RECV, Buffer);</p><p><b> }</b></p><p><b&
68、gt; /*</b></p><p> **設(shè)定本地及遠(yuǎn)程主機(jī)IP</p><p><b> */</b></p><p> void MYSOCK_SET_REMOTE(const TCHAR *remote_IP)</p><p><b> {</b></p>
69、<p><b> //功能還未實(shí)現(xiàn)</b></p><p><b> }</b></p><p><b> /*</b></p><p><b> **獲取本地主機(jī)名</b></p><p> ** 1.將主機(jī)名保存于成員變量HOS
70、TNAME中</p><p> ** 2.用wsprintf函數(shù)將主機(jī)名傳送到形參中</p><p><b> */</b></p><p> void MYSOCK_GET_HOSTNAME(TCHAR *HOST_BUFFER)</p><p><b> {</b></p>
71、<p> gethostname(HOSTNAME, sizeof(HOSTNAME));</p><p> wsprintf(HOST_BUFFER, "%s", HOSTNAME);</p><p><b> }</b></p><p><b> /*</b></p>
72、;<p> **獲取本地通信端口(字符串格式)</p><p> ** 直接用wsprintf函數(shù)轉(zhuǎn)換</p><p><b> */</b></p><p> void MYSOCKET_GET_PORTNUM(TCHAR *PORT_BUFFER)</p><p><b> {&l
73、t;/b></p><p> wsprintf(PORT_BUFFER, "%d", Local_Port_Num);</p><p><b> }</b></p><p><b> /*</b></p><p> **獲取本地通信地址(字符串格式)</p&g
74、t;<p> ** 1.用gethostbyname函數(shù)取得相關(guān)信息</p><p> ** 2.用inet_ntoa函數(shù)將網(wǎng)絡(luò)地址轉(zhuǎn)換為點(diǎn)分字符串形式</p><p> ** 3.用wsprintf函數(shù)轉(zhuǎn)換格式并輸出</p><p><b> */</b></p><p> void MY
75、SOCKET_GET_LOCALIP(TCHAR *IP_BUFFER)</p><p><b> {</b></p><p> HOSTENT=gethostbyname(HOSTNAME);</p><p> wsprintf(IP_BUFFER, "%s", inet_ntoa(*(struct in_addr
76、*)HOSTENT->h_addr_list[0]));</p><p><b> }</b></p><p><b> /*</b></p><p><b> **結(jié)束套接字過(guò)程</b></p><p> ** 1.注銷網(wǎng)絡(luò)異步選擇事件消息。</p>
77、<p> ** 2.關(guān)閉套接口</p><p> ** 3.卸載網(wǎng)絡(luò)動(dòng)態(tài)鏈接庫(kù)</p><p><b> */</b></p><p> void END_MYSOCKET(HWND &hwndDlg)</p><p><b> {</b></p>&l
78、t;p> WSAAsyncSelect(udp_sd, hwndDlg, 0, 0);</p><p> closesocket(udp_sd);</p><p> WSACleanup();</p><p><b> }</b></p><p><b> private:</b>
79、</p><p><b> /*</b></p><p> **WSADATA以及SOCKET變量</p><p> ** 相關(guān)函數(shù):MYSOCKET::INIT_MYSOCKET(HWND &hwndDlg)</p><p><b> */</b></p><
80、p> WSADATAwsaData;</p><p> SOCKET udp_sd;</p><p><b> /*</b></p><p> **1.Local_Port_Num ==> 本地端口號(hào)</p><p> ** Remote_Port_Num ==> 目的端口號(hào)</p
81、><p><b> **</b></p><p> **2.Local_PC ==> 本地通信結(jié)構(gòu)</p><p> ** Remote_PC ==> 遠(yuǎn)程通信結(jié)構(gòu)</p><p><b> **</b></p><p> **3.len ==>
82、"struct sockaddr"類型的長(zhǎng)度</p><p><b> **</b></p><p> ** 相關(guān)函數(shù):MYSOCKET::MYSOCKET(WORD local_port,WORD remote_port)</p><p><b> */</b></p><
83、p> WORD Local_Port_Num, Remote_Port_Num;</p><p> struct sockaddr_in Local_PC, Remote_PC;</p><p><b> int len;</b></p><p><b> /*</b></p><p>
84、; **數(shù)據(jù)接收、發(fā)送緩沖區(qū)</p><p> ** 相關(guān)函數(shù):MYSOCKET::MYSOCK_RECV(HWND &hwndDlg)</p><p> ** MYSOCKET::MYSOCK_SEND(HWND &hwndDlg)</p><p><b> **</b></p>&
85、lt;p><b> */</b></p><p> TCHAR Buffer[100];</p><p><b> /*</b></p><p><b> **保存本地主機(jī)名</b></p><p> ** 相關(guān)函數(shù):MYSOCKET::MYSOCK_GET_
86、HOSTNAME(TCHAR *HOST_BUFFER)</p><p><b> */</b></p><p> TCHAR HOSTNAME[10];</p><p><b> /*</b></p><p> ** struct hostent{</p><p>
87、 **char FAR * h_name;</p><p> **char FAR * FAR * h_aliases;</p><p> **short h_addrtype;</p><p> **short h_length;</p><p> **char FAR * FAR * h_addr_list;</
88、p><p><b> **};</b></p><p><b> **</b></p><p><b> */</b></p><p> struct hostent *HOSTENT;</p><p><b> };</b>
89、;</p><p> /////////////////////////////////////////////////////////////////////////</p><p> // 服務(wù)器端源代碼</p><p> // SERVER.CPP</p><p> #include <windows.h><
90、;/p><p> #include <winsock.h></p><p> #include "..\SERVER\resource.h"</p><p> #include "..\COMMON.H"</p><p> ////////////////////////////////
91、////////////</p><p> TCHAR PORT_BUFFER[10];</p><p> TCHAR HOST_BUFFER[10];</p><p> TCHAR IP_BUFFER[20];</p><p> //TCHAR IP_REMOTE_BUFFER[20];</p><p>
92、////////////////////////////////////////////</p><p> BOOL DialogProc(HWND hwndDlg,</p><p> UINT UMsg,</p><p> WPARAM wParam,</p><p> LPARAM IParam);</p><
93、p> ////////////////////////////////////////////</p><p> int WINAPI WinMain(HINSTANCE hInstance, </p><p> HINSTANCE hPrevInstance, </p><p> LPSTR lpCmdLine, </p><p&
94、gt; int nShowCmd)</p><p><b> {</b></p><p> DialogBoxParam(hInstance,</p><p> MAKEINTRESOURCE(IDD_SERVER),</p><p><b> NULL, </b></p>
95、<p> (DLGPROC)DialogProc,</p><p><b> 0);</b></p><p><b> return 0;</b></p><p><b> }</b></p><p> ///////////////////////////
96、//////////////////</p><p> BOOL DialogProc(HWND hwndDlg,</p><p> UINT UMsg,</p><p> WPARAM wParam,</p><p> LPARAM lParam)</p><p><b> {</b>
97、</p><p><b> /*</b></p><p> **!!構(gòu)造靜態(tài)CLIENT對(duì)象!!</p><p> ** 1.本地:127.0.0.1:4321</p><p> ** 2.遠(yuǎn)程:127.0.0.1:6321</p><p><b> */</b>&
98、lt;/p><p> static MYSOCKET SERVER(TEXT("127.0.0.1"), 4321, TEXT("127.0.0.1"), 6321);</p><p> switch(UMsg)</p><p><b> {</b></p><p> case
99、 WM_INITDIALOG:</p><p><b> /*</b></p><p><b> **初始化套接字</b></p><p><b> */</b></p><p> SERVER.INIT_MYSOCKET(hwndDlg);</p>&l
100、t;p><b> /*</b></p><p> **1.將本地IP地址保存于IP_BUFFER變量</p><p> **2.將其顯示在IDC_IP控件中</p><p><b> */</b></p><p> SERVER.MYSOCKET_GET_LOCALIP(IP_BUF
101、FER);</p><p> SetDlgItemText(hwndDlg, IDC_IP, IP_BUFFER);</p><p><b> /*</b></p><p> **1.將本地主機(jī)名保存于HOST_BUFFER變量</p><p> **2.將其顯示在IDC_HOST控件中</p>&
102、lt;p><b> */</b></p><p> SERVER.MYSOCK_GET_HOSTNAME(HOST_BUFFER);</p><p> SetDlgItemText(hwndDlg, IDC_HOST, HOST_BUFFER);</p><p><b> /*</b></p>
103、<p> **1.將本機(jī)通信端口保存于PORT_BUFFER變量</p><p> **2.將其顯示在IDC_PORT控件中</p><p><b> */</b></p><p> SERVER.MYSOCKET_GET_PORTNUM(PORT_BUFFER);</p><p> SetDlgIt
104、emText(hwndDlg, IDC_PORT, PORT_BUFFER);</p><p><b> /*</b></p><p> **1.將IP_BUFFER變量中的值顯示在IDC_IP_REMOTE控件中</p><p><b> */</b></p><p> SetDlgIte
105、mText(hwndDlg, IDC_IP_REMOTE, IP_BUFFER);</p><p> return TRUE;</p><p> case WM_COMMAND:</p><p> switch(LOWORD(wParam))</p><p><b> {</b></p><p
106、> case IDOK:</p><p><b> /*</b></p><p><b> **發(fā)送信息</b></p><p><b> */</b></p><p> SERVER.MYSOCK_SEND(hwndDlg);</p><p
107、><b> break;</b></p><p> case IDCANCEL:</p><p><b> /*</b></p><p><b> **關(guān)閉程序</b></p><p><b> */</b></p><
108、p> SERVER.END_MYSOCKET(hwndDlg);</p><p> EndDialog(hwndDlg, 0);</p><p><b> break;</b></p><p><b> }</b></p><p> return TRUE;</p>&
109、lt;p> case WM_USER+1:</p><p> switch(LOWORD(lParam))</p><p><b> {</b></p><p> case FD_READ:</p><p><b> /*</b></p><p><b&
110、gt; **接收信息并顯示</b></p><p><b> */</b></p><p> SERVER.MYSOCK_RECV(hwndDlg);</p><p><b> break;</b></p><p><b> }</b></p>
111、<p> return TRUE;</p><p><b> }</b></p><p> return FALSE;</p><p><b> }</b></p><p> //////////////////////////////////////////////////
112、///////////////////////</p><p> // 客戶機(jī)端源代碼</p><p> // CLIENT.CPP</p><p> //客戶機(jī)端與服務(wù)器端的代碼類似,在此就不列舉了</p><p> /////////////////////////////////////////////////////////
113、////////////////</p><p><b> // 資源頭文件</b></p><p> // RESOURCE.H</p><p> #define IDD_CLIENT 101</p><p> #define IDC_RECV
114、 1000</p><p> #define IDC_SEND 1001</p><p> #define IDC_IP 1007</p><p> #define IDC_PORT 1008<
115、;/p><p> #define IDC_HOST 1009</p><p> #define IDC_IP_REMOTE 1010</p><p> #define IDC_SETIP 1012</p><p>
116、 // Next default values for new objects</p><p> #ifdef APSTUDIO_INVOKED</p><p> #ifndef APSTUDIO_READONLY_SYMBOLS</p><p> #define _APS_NEXT_RESOURCE_VALUE 102</p>&
117、lt;p> #define _APS_NEXT_COMMAND_VALUE 40001</p><p> #define _APS_NEXT_CONTROL_VALUE 1013</p><p> #define _APS_NEXT_SYMED_VALUE 101</p><p><b>
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 眾賞文庫(kù)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 軟件課程設(shè)計(jì)報(bào)告--局域網(wǎng)聊天程序
- 軟件課程設(shè)計(jì)---局域網(wǎng)聊天程序
- 局域網(wǎng)聊天程序java課程設(shè)計(jì)
- vc局域網(wǎng)聊天室
- java課程設(shè)計(jì)--局域網(wǎng)聊天程序的設(shè)計(jì)與實(shí)現(xiàn)
- java課程設(shè)計(jì)---局域網(wǎng)聊天程序的設(shè)計(jì)與實(shí)現(xiàn)
- java課程設(shè)計(jì)---局域網(wǎng)聊天程序的設(shè)計(jì)與實(shí)現(xiàn)
- 基于java的局域網(wǎng)聊天系統(tǒng)-課程設(shè)計(jì)報(bào)告
- 基于java的局域網(wǎng)聊天系統(tǒng)-課程設(shè)計(jì)報(bào)告
- 課程設(shè)計(jì)--基于qt的局域網(wǎng)聊天室
- vc++課程設(shè)計(jì)--聊天室程序設(shè)計(jì)
- 《vc++面向?qū)ο蟪绦蛟O(shè)計(jì)》課程設(shè)計(jì)任務(wù)書
- vc++網(wǎng)絡(luò)聊天軟件課程設(shè)計(jì)
- 基于java局域網(wǎng)聊天程序設(shè)計(jì)與實(shí)現(xiàn)
- 基于java局域網(wǎng)聊天程序設(shè)計(jì)與實(shí)現(xiàn)
- 畢業(yè)設(shè)計(jì)--局域網(wǎng)聊天系統(tǒng)
- 局域網(wǎng)聊天系統(tǒng)畢業(yè)設(shè)計(jì)
- 面向?qū)ο蟪绦蛟O(shè)計(jì)與vc++實(shí)踐
- vc++課程設(shè)計(jì)----用winsock實(shí)現(xiàn)聊天
- 局域網(wǎng)畢業(yè)論文---局域網(wǎng)聊天軟件
評(píng)論
0/150
提交評(píng)論