網(wǎng)絡(luò)編程實(shí)驗(yàn)指導(dǎo)書.doc_第1頁(yè)
網(wǎng)絡(luò)編程實(shí)驗(yàn)指導(dǎo)書.doc_第2頁(yè)
網(wǎng)絡(luò)編程實(shí)驗(yàn)指導(dǎo)書.doc_第3頁(yè)
網(wǎng)絡(luò)編程實(shí)驗(yàn)指導(dǎo)書.doc_第4頁(yè)
網(wǎng)絡(luò)編程實(shí)驗(yàn)指導(dǎo)書.doc_第5頁(yè)
已閱讀5頁(yè),還剩44頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

網(wǎng)絡(luò)編程課程實(shí)驗(yàn)指導(dǎo)書實(shí)驗(yàn)七 HTTP協(xié)議客戶端編程實(shí)現(xiàn)1 實(shí)驗(yàn)?zāi)康呐c要求掌握瀏覽web網(wǎng)頁(yè)的原理,深入理解HTTP原理以及HTML語(yǔ)言的功能,運(yùn)用流式套接字下載web網(wǎng)頁(yè)文件,分別用文本方式和瀏覽器方式打開(kāi)下載的網(wǎng)頁(yè)文件。同時(shí)運(yùn)用ChtmlView類編寫瀏覽器軟件。運(yùn)用ChtmlView類開(kāi)發(fā)瀏覽器程序,比較兩者的異同.2、實(shí)驗(yàn)內(nèi)容第一部分:編寫并理解程序,利用流式套接字與web服務(wù)器建立TCP連接,然后向服務(wù)器發(fā)送Get命令,接收服務(wù)器的內(nèi)容,把接收到的信息保存在一個(gè)文件中,然后打開(kāi)該文件,觀察文件的內(nèi)容.第二部分: 運(yùn)用ChtmlView類開(kāi)發(fā)瀏覽器程序3 實(shí)驗(yàn)原理模擬explorer部分功能,與web服務(wù)器的80端口建立TCP連接,接下來(lái)向web服務(wù)器發(fā)送一Get命令,服務(wù)器會(huì)把應(yīng)答信息和web網(wǎng)頁(yè)的內(nèi)容傳輸過(guò)來(lái).4、實(shí)驗(yàn)步驟編寫并調(diào)試程序,選擇一個(gè)web服務(wù)器,尋找共IP地址,如:邵陽(yáng)學(xué)院 0搜狐 新浪 13在程序中填入該web服務(wù)器的Ip地址,運(yùn)行程序,打開(kāi)接收的文本文件,觀察文件的內(nèi)容。并在實(shí)驗(yàn)報(bào)告中填寫下述內(nèi)容。接收文件的第一部分的應(yīng)答信息內(nèi)容是什么? 接收文件的第二部分的內(nèi)容是什么?用ChtmlView類開(kāi)發(fā)瀏覽器程序有什么特點(diǎn)?主要儀器設(shè)備:安裝有VC+6.0的PC機(jī)。要求撰寫實(shí)驗(yàn)報(bào)告,填寫實(shí)驗(yàn)結(jié)果。附錄:第一部分的程序如下#pragma comment(lib,ws2_32.lib)#include #include #include void main()WSADATA wsaData;SOCKET s;FILE *fp1;/文件指針SOCKADDR_IN saddr;int result;/整形變量,用于記錄接收數(shù)據(jù)的字節(jié)數(shù)int port=80;/http服務(wù)器的默認(rèn)端口WSAStartup(MAKEWORD(2,2),&wsaData);s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);/創(chuàng)建TCP套接字saddr.sin_family=AF_INET;saddr.sin_port=htons(port);saddr.sin_addr.S_un.S_addr=inet_addr(0);/的IP地址connect(s,(SOCKADDR*) &saddr, sizeof(saddr);/請(qǐng)求與web服務(wù)器建立TCP連接char sendbuff400,strB1025;/定義發(fā)送緩沖區(qū)和接收緩沖區(qū)strcpy(sendbuff,GET /index.html HTTP/1.1rnHost:rnrn);/字符串拷貝send(s,sendbuff,strlen(sendbuff),0);/傳送http請(qǐng)求報(bào)文fp1=fopen(E:pp1.html,w);/打開(kāi)E:pp.html,把接收?qǐng)?bào)文保存在該文件中result = 1;/以下每次最多只接收1024字節(jié),其中result為接收的字節(jié)數(shù)while(result0)strset(strB, );result=recv(s,strB,1024,0);/接收http應(yīng)答報(bào)文fwrite(strB,1,result,fp1);/把strB的數(shù)據(jù)寫入fp所指的文件,以1個(gè)字節(jié)為單位,寫入result個(gè)字節(jié)strBresult=0;/為顯示在屏幕上,加字符串結(jié)束標(biāo)記printf(%s,strB);/以字符串的形式顯示的屏幕上 /實(shí)際接收的字節(jié)數(shù)大于0,繼續(xù)接收f(shuō)close(fp1);/關(guān)閉文件closesocket(s);/關(guān)閉套接字WSACleanup();/關(guān)閉動(dòng)態(tài)鏈接庫(kù)第二部分的操作如下1 建立工程SelfBrowser基于”單文檔”, 工具欄樣式為:”類似IE”,最后一步的CselfBrowserView基于ChtmlView類2 打開(kāi)資源視圖(ResourceView),點(diǎn)擊對(duì)話框資源(Dialog),再點(diǎn)擊IDR_MAINFRAME選項(xiàng)卡,如圖所示:剪切“TODO:對(duì)話框布局”,在該位置添加一編輯框和命令按鈕,把命令按鈕的標(biāo)題改為”瀏覽”,把編輯框的ID號(hào)改為”ID_EDIT_ADDRESS”,如圖所示3 點(diǎn)擊“建立類向?qū)А背鰰?huì)現(xiàn)如下界面,選定”Select an existing class”后,點(diǎn)擊”O(jiān)K”,出現(xiàn)下面的界面選定CmainFrame類后,點(diǎn)擊”select”再點(diǎn)擊“確定”后,完成建立類向?qū)У牟僮鳌? 雙擊“瀏覽”按鈕,為該按鈕添加成員函數(shù),其代碼如下:CString sWebAddress;m_wndDlgBar.GetDlgItem(IDC_EDIT_ADDRESS)-GetWindowText(sWebAddress);(CHtmlView*)GetActiveView()-Navigate(sWebAddress);5 打開(kāi)類視圖,找到“CSelfBrowserView”類的OnInitialUpdate函數(shù)更改其中的內(nèi)容,使其的默認(rèn)網(wǎng)頁(yè)為””6 打開(kāi)”MainFrm.h”文件,在類(CMainFrame)定義中加入成員函數(shù)的聲明afx_msg void OnInputAddress();在”MainFrm.cpp”中添加函數(shù)的實(shí)現(xiàn)afx_msg void CMainFrame:OnInputAddress()/其代碼與“瀏覽”按鈕的代碼相同再在該文件BEGIN_MESSAGE_MAP與END_MESSAGE_MAP之間添加如下代碼:ON_COMMAND(IDOK,OnInputAddress)7 打開(kāi)資源視圖,添加如下菜單項(xiàng),各菜單項(xiàng)的ID標(biāo)志和相關(guān)信息菜單項(xiàng)IDPrompt代碼CSelfBrowserView后退(&B)ID_BACK轉(zhuǎn)到上一頁(yè)n后退GoBack()前進(jìn)(&F)ID_FORWARD轉(zhuǎn)到下一頁(yè)n前進(jìn)GoForward()主頁(yè)(&H)ID_HOME轉(zhuǎn)到主頁(yè)n主頁(yè)GoHome()停止(&S)ID_STOP停止加載頁(yè)n停止Stop()刷新(&R)ID_REFRESH刷新當(dāng)前頁(yè)n刷新Refresh()源文件(&C)ID_CODE顯示網(wǎng)頁(yè)文件n源文件進(jìn)入”查看功能”,選定”建立類向?qū)А?,選定”CSelfBrowserView”類,找到各菜單項(xiàng)對(duì)應(yīng)的ID號(hào),添加其相應(yīng)的成員函數(shù)8 自定義工具欄在資源視圖中點(diǎn)擊ToolBar-IDR_MAINFRAME添加圖標(biāo),畫出圖標(biāo)的圖形,按回車,為圖標(biāo)定義ID及相關(guān)信息圖標(biāo)項(xiàng)IDPrompt代碼CSelfBrowserView后退(&B)ID_TOOLBACK轉(zhuǎn)到上一頁(yè)n后退GoBack()前進(jìn)(&F)ID_TOOLFORWARD轉(zhuǎn)到下一頁(yè)n前進(jìn)GoForward()進(jìn)入”查看功能”,選定”建立類向?qū)А?,選定”CSelfBrowserView”類,找到各圖標(biāo)項(xiàng)對(duì)應(yīng)的ID號(hào),添加其相應(yīng)的成員函數(shù)9 使標(biāo)題標(biāo)隨頁(yè)面不同而改變?yōu)橐晥D類CSelfBrowserView添加虛成員函數(shù)OnDocumentComplete()添加代碼如下:(CMainFrame*)GetParentFrame()-SetURL(lpszURL);GetDocument()-SetTitle(lpszURL);在MainFrm.h文件的類定義中聲明void SetURL(LPCTSTR lpszURL);在MainFrm.cpp中實(shí)現(xiàn)該方法,其代碼為m_wndDlgBar.GetDlgItem(IDC_EDIT_ADDRESS)-SetWindowTextA(lpszURL);在SelfBrowserView.cpp文件的前面添加如下代碼#include “MainFrm.h”10 使用WinInet類的功能為工程添加一個(gè)對(duì)話框點(diǎn)擊”資源視圖”-Dialog-右擊(選插入Dialog)得到一個(gè)對(duì)話框,刪除“確定按鈕”,把“取消”按鈕改為”關(guān)閉”。添加一個(gè)文本框。如下圖所示:為工程添加一個(gè)新類,類名為CHtmlCodeViewDlg,其基類為CDialog,Dialog ID為IDD_DIALOG1添加菜單項(xiàng)”源文件”的成員函數(shù)與代碼查看-類向?qū)?選CselfBrowserView類,選中ID_CODE,選COMMAND雙擊添加的代碼如下:CHtmlCodeViewDlg dlg;dlg.DoModal();在文件SelfBrowserView.cpp的前部添加如下代碼#include “HtmlCodeViewDlg.h”在HtmlCodeViewDlg.cpp文件的前部包含如下代碼#include “MainFrm.h”#include “afxinet.h”在MainFrm.h的類定義中,把變量m_wndDlgBar的聲明改為public在CHtmlCodeViewDlg類中,為編輯框添加成員變量m_htmlCode :CString 添加CHtmlCodeViewDlg類的初始成員函數(shù)點(diǎn)擊”建立類向?qū)А?選擇CHtmlCodeViewDlg類,在object ID欄選CHtmlCodeViewDlg,在右邊message欄選WM_INITDIALOG雙擊添加如下代碼:CWaitCursor wait;CInternetSession session(Self Net);CStdioFile *pFile=NULL;CString sWebAddress;(CMainFrame*)GetParentFrame()-m_wndDlgBar).GetDlgItem(IDC_EDIT_ADDRESS)-GetWindowText(sWebAddress);pFile=session.OpenURL(sWebAddress);if(pFile!=NULL)CString str,allText=,crlf=rn;while(pFile-ReadString(str)allText+=crlf+str;this-m_htmlCode=allText;UpdateData(false);pFile-Close();實(shí)驗(yàn)六 Ping命令的編程實(shí)現(xiàn)1 實(shí)驗(yàn)?zāi)康呐c要求掌握原始套接字的使用,深入理解ICMP協(xié)議和IP協(xié)議的首部結(jié)構(gòu),理解ping命令的工作原理,運(yùn)用原始套接字實(shí)現(xiàn)ping命令的功能,注意計(jì)算校驗(yàn)和的算法.2、實(shí)驗(yàn)內(nèi)容編寫并理解程序,利用原始套接字傳輸ICMP包給目標(biāo)主機(jī),實(shí)現(xiàn)ping命令的功能。實(shí)現(xiàn)結(jié)果如下:ping 0的結(jié)果3 實(shí)驗(yàn)原理Ping命令的功能是測(cè)試兩臺(tái)主臺(tái)是否連通,由一臺(tái)主機(jī)發(fā)送一個(gè)ICMP的回送/請(qǐng)求與應(yīng)答報(bào)文至另一臺(tái)主機(jī),然后接收應(yīng)合報(bào)文,測(cè)試數(shù)據(jù)發(fā)送與接收的往返時(shí)間,IP包中的TTL值以及ICMP報(bào)文中附加數(shù)據(jù)的字節(jié)數(shù).4、實(shí)驗(yàn)步驟首先確定一臺(tái)開(kāi)啟的機(jī)器,可以是Internet網(wǎng)絡(luò)上的任何一臺(tái)主機(jī),也可以是局域網(wǎng)上的一臺(tái)工作站,但必須保證該機(jī)器是開(kāi)啟的,并沒(méi)有禁用ICMP請(qǐng)求應(yīng)答報(bào)文,找到該機(jī)器的IP地址,填入程序中的相應(yīng)位置上,然后運(yùn)行程序,記錄結(jié)果。并在實(shí)驗(yàn)報(bào)告中填寫下述內(nèi)容。目的主機(jī)的IP地址為:_每次發(fā)送ICMP包的個(gè)數(shù):_運(yùn)行結(jié)果:ICMP首部應(yīng)填的內(nèi)容主要儀器設(shè)備:安裝有VC+6.0的PC機(jī)。要求撰寫實(shí)驗(yàn)報(bào)告,填寫實(shí)驗(yàn)結(jié)果。附錄:參考程序#include /Winsock API頭文件#include #include #pragma comment(lib,ws2_32.lib) /Winsock API連接庫(kù)文件/BYTEunsigned char,自定義類型/USHORTunsigned short,自定義類型/ULONGunsigned long,自定義類型typedef unsigned char BYTE;typedef unsigned short USHORT;typedef unsigned long UNLONG;/IP首部結(jié)構(gòu)typedef struct iphdr/IP首部結(jié)構(gòu)體BYTE h_len:4; /首部長(zhǎng)度指的是IP層頭部占32bit字的數(shù)目 /(也就是IP層頭部包含多少個(gè)4字節(jié),實(shí)際字節(jié)數(shù)4*hlen),BYTE version:4; /IP版本號(hào)BYTE tos; /服務(wù)類型TOSUSHORT total_len; /IP包總長(zhǎng)度 USHORT ident; /標(biāo)識(shí)USHORT frag_and_flags; /標(biāo)志位BYTE ttl; /生存時(shí)間BYTE proto; /協(xié)議USHORT checksum; /IP首部校驗(yàn)和ULONG sourceIP; /源IP地址(32位)ULONG destIP; /目的IP地址(32位)IpHeader;/*ICMP頭 結(jié)構(gòu)*/typedef struct _ihdrBYTE i_type; /類型 發(fā)出的ICMP為8(ICMP_ECHO_REQUEST),接受到的ICMP為0BYTE i_code; /代碼USHORT i_cksum; /ICMP包校驗(yàn)和USHORT i_id; /識(shí)別號(hào)(一般用進(jìn)程號(hào)作為標(biāo)識(shí)號(hào))USHORT i_seq; /報(bào)文序列號(hào)(一般設(shè)置為0)IcmpHeader;USHORT checksum(USHORT *,int); /函數(shù)聲明:計(jì)算ICMP包校驗(yàn)和void main()/初始化SocketWSADATA wsaData;WSAStartup(MAKEWORD(2,2), /Socket版本號(hào) &wsaData /指向WSADATA數(shù)據(jù)結(jié)構(gòu)的指針 );SOCKET sockRaw;/定義原始套接字/創(chuàng)建原始套接字sockRaw=socket(AF_INET,/協(xié)議族(AF_INET: TCP_IP) 3,/SOCK_RAW,/套接字類型(原始套接字) IPPROTO_ICMP/協(xié)議類型(ICMP協(xié)議) );/設(shè)置目的IPchar ICMP_DEST_IP20;/目標(biāo)主機(jī)IP點(diǎn)分十進(jìn)制地址sprintf(ICMP_DEST_IP,0); /IP目標(biāo)地址SOCKADDR_IN dest,from;/地址結(jié)構(gòu)memset(&dest,0,sizeof(dest);dest.sin_addr.S_un.S_addr=inet_addr(ICMP_DEST_IP);dest.sin_family=AF_INET;char *icmp_data;/ICMP包地址指針int attachsize=32;/發(fā)送的ICMP數(shù)據(jù)包附加字節(jié)數(shù),本程序默認(rèn)為32字節(jié)char *attachdata;/ICMP包附加數(shù)據(jù)存貯區(qū)指針attachdata=(char*)malloc(attachsize);/創(chuàng)建一個(gè)32字節(jié)的存貯區(qū)memset(attachdata,a,attachsize);/ICMP包數(shù)據(jù)部分 填充attachsize字節(jié)aint datasize=sizeof(IcmpHeader)+attachsize;/ICMP數(shù)據(jù)包總大小(頭+體)icmp_data=(char*)malloc(datasize);/根據(jù)上面計(jì)算的結(jié)果為ICMP包分配內(nèi)存memset(icmp_data,0,datasize);/清0(IcmpHeader *)icmp_data)-i_type=8;/類型為8(IcmpHeader *)icmp_data)-i_code=0;/代碼為0(IcmpHeader *)icmp_data)-i_id=1;/(USHORT)GetCurrentProcessId();(IcmpHeader *)icmp_data)-i_seq=0;/序列號(hào) 0 memcpy(icmp_data+sizeof(IcmpHeader),attachdata,attachsize);/把ICMP包數(shù)據(jù)部分復(fù)制過(guò)來(lái)/計(jì)算ICMP包校驗(yàn)和(IcmpHeader *)icmp_data)-i_cksum=0;/使ICMP校驗(yàn)和字段初始化為0(IcmpHeader *)icmp_data)-i_cksum=checksum(USHORT *)icmp_data,datasize);/調(diào)用函數(shù)計(jì)算校驗(yàn)和printf(Pinging %s with %d bytes of data:nn,ICMP_DEST_IP,attachsize);DWORD timeuse;/往返時(shí)間int n=20;/發(fā)送數(shù)據(jù)包個(gè)數(shù),循環(huán)次數(shù)int fromlen=sizeof(SOCKADDR);/地址長(zhǎng)度char *recvbuf;/接收ICMP應(yīng)答包存貯區(qū)域指針recvbuf=(char*)malloc(300);/接收應(yīng)答ICMP的IP包存貯區(qū),300字節(jié)的存貯區(qū)int ret;/API函數(shù)的返回值,接收數(shù)據(jù)函數(shù)的返回值DWORD start;/發(fā)送ICMP包起始時(shí)間for(int i=1;ih_len*4;/IP首部長(zhǎng)度attachlen=ret-iphdrlen-sizeof(IcmpHeader);/計(jì)算附加數(shù)據(jù)段的大小printf(Reply from %s: bytes=%d time=%dms TTL=%dn,ICMP_DEST_IP,attachlen,timeuse,(IpHeader *)recvbuf)-ttl);/IP地址 附加數(shù)據(jù)長(zhǎng)度 往返時(shí)間 TTLclosesocket(sockRaw);/關(guān)閉套接字WSACleanup();/釋放動(dòng)態(tài)鏈接庫(kù)system(pause);/計(jì)算ICMP數(shù)據(jù)包校驗(yàn)和USHORT checksum(USHORT *buffer,int size)LONG cksum=0;while(size1)cksum=cksum+*buffer;buffer+;size-=sizeof(USHORT);if(size)cksum=cksum+*(BYTE*)buffer;cksum=(cksum16)+(cksum&0xffff);cksum=(cksum16)+(cksum&0xffff);return (USHORT) (cksum);實(shí)驗(yàn)五 聊天軟件的開(kāi)發(fā)1 實(shí)驗(yàn)?zāi)康呐c要求掌握互連網(wǎng)中繼聊天協(xié)議IRC的原理,理解聊天軟件的工作模式,基于VC+6.0設(shè)計(jì)一個(gè)簡(jiǎn)單的群聊程序.2、實(shí)驗(yàn)內(nèi)容三人以上為一組,其中一個(gè)同學(xué)為群聊軟件的服務(wù)器端,另外同學(xué)為群聊軟件客戶端,服務(wù)器開(kāi)啟后公布其IP地址和端口號(hào),客戶端用服務(wù)器的IP地址和端口號(hào)進(jìn)行登錄,觀察服務(wù)器與客戶端的顯示的結(jié)果,然后由客戶端發(fā)送群聊消息,觀察服務(wù)器與各客戶端的顯示結(jié)果.3 實(shí)驗(yàn)原理聊天程序一般采用互連網(wǎng)中繼聊天協(xié)議,即雙方即時(shí)通信的過(guò)程中必須通過(guò)第三方中轉(zhuǎn),第三方為服務(wù)器,聊天程序一般采用UDP協(xié)議,在基于UDP協(xié)議的基礎(chǔ)中,聊天天遵守一種約定某一種約定,這種約定規(guī)定了”進(jìn)行聊天室”,”發(fā)送聊天信息”和”離開(kāi)聊天室”數(shù)據(jù)傳輸格式,中轉(zhuǎn)者(服務(wù)器)通過(guò)接收客戶端不同的數(shù)據(jù)格式來(lái)進(jìn)行判斷消息發(fā)送者的欲進(jìn)行的操作.然后對(duì)消息進(jìn)行處理后再進(jìn)行轉(zhuǎn)發(fā).登錄消息格式:第一個(gè)字節(jié)為1+用戶名離開(kāi)消息格式:第一個(gè)字節(jié)為3+用戶名群聊消息格式:第一個(gè)字節(jié)為2+用戶名+”:”+群聊消息。服務(wù)器根據(jù)接收到的不同消息格式做出不同的處理。4、實(shí)驗(yàn)步驟3人以上為一組,一人確定為服務(wù)器,公布自己的IP地址和端口號(hào),并針對(duì)該IP地址與端口號(hào)運(yùn)行服務(wù)器程序,進(jìn)行“開(kāi)啟服務(wù)器”操作,客戶端針對(duì)服務(wù)器的IP地址與端口號(hào)運(yùn)行客戶端程序進(jìn)行登錄,發(fā)送聊天消息,離開(kāi)聊天室。實(shí)驗(yàn)完成后,總結(jié)實(shí)驗(yàn)結(jié)果。主要儀器設(shè)備:安裝有VC+6.0的PC機(jī)。要求撰寫實(shí)驗(yàn)報(bào)告,填寫實(shí)驗(yàn)結(jié)果。附錄:操作指南注意,如采用復(fù)制操作,則自始至終均需與該附錄的相同.一、服務(wù)器端1 建立工程SelfRoom基于對(duì)話框, 不包含window Sockets類添加控件如下圖所示2 為控件添加成員變量編號(hào)控件名稱ControlValue1IP地址ServerIP 2端口號(hào)ServerPortsPort :CString3顯示列表框m_ListWords4開(kāi)啟按鈕m_Start5關(guān)閉按鈕m_Close6退出按鈕m_Quit3 添加”開(kāi)啟”、”關(guān)閉”按鈕的成員函數(shù)4 在SelfRoomDlg.h文件的類定義前添加如下幾行代碼#pragma comment(lib,ws2_32.lib”)#include #include #include /定義一個(gè)結(jié)構(gòu)體,用戶記錄在線用戶的信息typedef struct userchar usrname10;/用戶名unsigned long ip;/IP地址unsigned short int port;/端口號(hào) User,*pUser;在SelfRoomDlg.h文件的類定義中添加如下代碼,即m_server等是該類的成員變量:SOCKET m_server;/套接字變量SOCKADDR_IN saddr,caddr;/兩個(gè)三元組地址int usrcont;/記錄聊天室在線人數(shù)的變量User user100;/用于保存在線用戶的信息5 在CselfRoomDlg類的初始化成員函數(shù)的尾部(return語(yǔ)句前)添加如下代碼WSADATA wsaData;WSAStartup(MAKEWORD(2,2),&wsaData);/ 加載動(dòng)態(tài)鏈接庫(kù)usrcont=0;/在線人數(shù)初始化為0m_Close.EnableWindow(false);/關(guān)閉按鈕不可用6 添加 ”開(kāi)啟”、”關(guān)閉”和”退出”按鈕的成員函數(shù)的代碼:” 開(kāi)啟”按鈕UpdateData(true);m_server=socket(AF_INET,SOCK_DGRAM,0);WSAAsyncSelect(m_server,m_hWnd,20000,FD_READ|FD_CLOSE);BYTE nFild4;CString sIP;ServerIP.GetAddress(nFild0,nFild1,nFild2,nFild3);sIP.Format(%d.%d.%d.%d,nFild0,nFild1,nFild2,nFild3);saddr.sin_family=AF_INET;saddr.sin_port=htons(atoi(sPort);saddr.sin_addr.S_un.S_addr=inet_addr(sIP);int len=sizeof(SOCKADDR);bind(m_server,(SOCKADDR*)&saddr,len);/使套接字綁定地址m_ListWords.InsertString(-1,聊天室已開(kāi)啟,等待成員加入);m_Start.EnableWindow(false);/使開(kāi)啟按鈕不可用m_Close.EnableWindow(true);/用離開(kāi)按紐可用m_Quit.EnableWindow(false);/退了按紐不可用”關(guān)閉”按鈕if(usrcont)AfxMessageBox(還有用戶沒(méi)有下線,不能關(guān)閉!);elsem_Start.EnableWindow(true);m_Close.EnableWindow(false);m_Quit.EnableWindow(true);closesocket(m_server);”退出”按鈕WSACleanup();/釋放動(dòng)態(tài)鏈接庫(kù)8 為主對(duì)話框類CSelfRoomDlg添加虛成員函數(shù)PreTranslateMessage(),并添加如下代碼:if(pMsg-message=20000)this-ReceiveData();else9為主對(duì)話框類CSelfRoomDlg添加成員函數(shù)void ReceiveData();添加的方法是:先在頭文件SelfRoomDlg.h的類定義中進(jìn)行成員函數(shù)聲明,然后在SelfRoomDlg.cpp文件中進(jìn)行函數(shù)的實(shí)現(xiàn),這兩個(gè)函數(shù)的代碼如下:ReceiveData()函數(shù)char buff100;/接收數(shù)據(jù)緩沖區(qū)memset(buff,0,100);/把緩沖區(qū)每個(gè)字節(jié)置0int len=sizeof(SOCKADDR);/地址長(zhǎng)度int num=recvfrom(m_server,buff,100,0,(SOCKADDR*)&caddr,&len);/從套接字接收數(shù)據(jù)至buff中WSAAsyncSelect(m_server,m_hWnd,20000,FD_READ|FD_CLOSE);pUser ptemp;/定義一個(gè)結(jié)構(gòu)體指針if(buff0=1)/接收的是登錄信息ptemp=user+usrcont;/指向userusrcont,user數(shù)組的第一個(gè)空單元memcpy(ptemp-usrname,buff+1,10);/保存用戶名ptemp-ip=ntohl(caddr.sin_addr.S_un.S_addr);/保存地址ptemp-port=ntohs(caddr.sin_port);/保存端口號(hào)CString sTemp;/定義一個(gè)臨時(shí)變量sTemp.Format(%s,%s:%d,ptemp-usrname,inet_ntoa(caddr.sin_addr),ptemp-port); /存放用戶名和地址信息至sTemp中m_ListWords.InsertString(-1,sTemp+已加入);/顯示sTemp.Format(%s登錄成功,sTemp);/sendto(m_server,sTemp,sTemp.GetLength(),0,(SOCKADDR*)&caddr,len);/向登錄用戶發(fā)登錄成功的信息sTemp.Format(%s已加入,ptemp-usrname);/向已在線的用戶發(fā).已加入的消息for(int i=0;iip);caddr.sin_port=htons(ptemp-port);sendto(m_server,sTemp,sTemp.GetLength(),0,(SOCKADDR*)&caddr,len);usrcont+;/在線用戶數(shù)增加1else if(buff0=3)User pptemp;/定義一結(jié)構(gòu)體變量ptemp=&pptemp;/ptem指向這一結(jié)構(gòu)體變量memcpy(ptemp-usrname,buff+1,10);/取出離開(kāi)用戶的用戶名至ptemp-usrname成員中CString sname;sname.Format(%s,ptemp-usrname);/用戶名取至sname變量中CString sTemp;sTemp.Format(%s,%s:%d,ptemp-usrname,inet_ntoa(caddr.sin_addr),ntohs(caddr.sin_port);m_ListWords.InsertString(-1,sTemp+已離開(kāi));sTemp.Format(%s與服務(wù)器斷開(kāi),sTemp);sendto(m_server,sTemp,sTemp.GetLength(),0,(SOCKADDR*)&caddr,len);/向申請(qǐng)離開(kāi)的用戶發(fā)消息sTemp.Format(%s已離開(kāi),ptemp-usrname);int temp;/記錄申請(qǐng)離開(kāi)的用戶在user數(shù)組的位置/向其它用戶發(fā)送for(int i=0;iusrname,sname)=0)temp=i;elsecaddr.sin_addr.S_un.S_addr=htonl(ptemp-ip);caddr.sin_port=htons(ptemp-port);sendto(m_server,sTemp,sTemp.GetLength(),0,(SOCKADDR*)&caddr,len); /刪除user數(shù)組中的第temp個(gè)元素,后面元素前移一個(gè)位置 for(i=temp;iip=ntohl(caddr.sin_addr.S_un.S_addr);ptemp-port=ntohs(caddr.sin_port);CString sTemp,sTemp1,sTemp2;sTemp.Format(%s:%s:%d,sname,inet_ntoa(caddr.sin_addr),ptemp-port);str=str.Right(str.GetLength()-(n+1);sTemp1.Format(%s,str);SOCKADDR_IN tempaddr;sTemp2.Format(%s說(shuō):%s,sTemp,sTemp1);m_ListWords.InsertString(-1,sTemp2);for(int i=0;iusrname,sname)tempaddr.sin_family=AF_INET;tempaddr.sin_addr.S_un.S_addr=htonl(ptemp-ip);tempaddr.sin_port=htons(ptemp-port);sendto(m_server,sTemp2,sTemp2.GetLength(),0,(SOCKADDR*)&tempaddr,len);以上工作完成后,便可以編譯運(yùn)行二、客戶端1 建立工程SelfChat基于對(duì)話框, 不包含window Sockets類添加控件如下圖所示2 為控件添加成員變量編號(hào)控件名稱ControlValue1您的昵稱編輯框m_Usrm_strName :CString2端口號(hào)m_portstrport :CString3發(fā)送信息框m_EditWordsm_strMessage :CString4顯示列表框m_ListWords4聊天室IP地址ServerIP3 添加“登錄”、“離開(kāi)”、“發(fā)送”、“退出”按鈕的成員函數(shù)4 打開(kāi)文件SelfChatDlg.h,在SelfChatDlg.h類定義的前面添加如下代碼#pragma comment(lib,”ws2_32.lib”)#include #include #include typedef struct infochar type;char sname10; INFO,*pINFO;在CSelfChatDlg類定義中添加如下代碼,即m_client等是該類的成員變量:SOCKET m_client;SOCKADDR_IN saddr;5 在CSelfChatDlg類的初始化函數(shù)OnInitDialog()的尾部(return語(yǔ)句前)添加以下代碼WSADATA wsaData;WSAStartup(MAKEWORD(2,2),&wsaData);/打開(kāi)動(dòng)態(tài)鏈接庫(kù)6 添加“登錄”、“離開(kāi)”、“發(fā)送”、“退出”按鈕的成員函數(shù)的代碼:”登錄”按鈕成員函數(shù)代碼UpdateData(true);m_client=socket(AF_INET,SOCK_DGRAM,0);WSAAsyncSelect(m_client,m_hWnd,10000,FD_READ);BYTE nFild4;CString sip;ServerIP.GetAddress(nFild0,nFild1,nFild2,nFild3);sip.Format(%d.%d.%d.%d,nFild0,nFild1,nFild2,nFild3);saddr.sin_family=AF_INET;saddr.sin_addr.S_un.S_addr=inet_addr(sip);saddr.sin_port=htons(atoi(strport);char *buff=(char*)malloc(sizeof(INFO);memset(buff,0,sizeof(INFO);pINFO pu=(pINFO)buff;pu-type=1;memcpy(pu-sname,m_strName,m_strName.GetLength();int len=sizeof(SOCKADDR);sendto(m_client,buff,sizeof(INFO),0,(SOCKADDR*)&saddr,len);”離開(kāi)”按鈕成員函數(shù)代碼UpdateData(true);m_client=socket(AF_INET,SOCK_DGRAM,0);WSAAsyncSelect(m_client,m_hWnd,10000,FD_READ|FD_CLOSE);BYTE nFild4;CString sip;ServerIP.GetAddress(nFild0,nFild1,nFild2,nFild3);sip.Format(%d.%d.%d.%d,nFild0,nFild1,nFild2,nFild3);saddr.sin_family=AF_INET;saddr.sin_addr.S_un.S_addr=inet_addr(sip);saddr.sin_port=htons(atoi(strport);char *buff=(char*)malloc(sizeof(INFO);memset(buff,0,sizeof(INFO);pINFO pu=(pINFO)buff;pu-type=3;memcpy(pu-sname,m_strName,m_strName.GetLength();CString pp;pp.Format(%d%s,pu-type,pu-sname);int len=sizeof(SOCKADDR);sendto(m_client,buff,sizeof(INFO),0,(SOCKADDR*)&saddr,len);closesocket(m_client);”發(fā)送”按鈕成員函數(shù)代碼UpdateData(true);char *buff=(char*)malloc(sizeof(INFO);char pu=2;m_ListWords.InsertString(-1,本人已發(fā)送:+m_strMessage);CString pp;pp.Format(%d%s:%s,pu,m_strName,m_strMessage+0);int len=sizeof(SOCKADDR);sendto(m_client,pp,pp.GetLength(),0,(SOCKADDR*)&saddr,len);”退出”按鈕成員函數(shù)代碼WSACleanup();/釋放socket庫(kù)7為主對(duì)話框類CSelfChatDlg添加虛成員函數(shù)PreTranslateMessage(),并添加如下代碼:if(pMsg-message=10000)this-ReceiveData();else8為主對(duì)話框類CSelfChatDlg添加成員函數(shù)void ReceiveData();添加的方法是:先在頭文件SelfChatDlg.h的類定義中進(jìn)行成員函數(shù)聲明,然后在SelfChatDlg.cpp文件中進(jìn)行函數(shù)的實(shí)現(xiàn),這兩個(gè)函數(shù)的代碼如下:ReceiveData()函數(shù)char buff100;SOCKADDR_IN caddr;memset(buff,0,100);int len=sizeof(SOCKADDR);int num=recvfrom(m_client,buff,100,0,(SOCKADDR*)&caddr,&len);WSAAsyncSelect(m_client,m_hWnd,10000,FD_READ|FD_CLOSE);m_ListWords.InsertString(-1,buff);以上工作完成后,便可以編譯運(yùn)行實(shí)驗(yàn)四 數(shù)據(jù)報(bào)套接字的編程實(shí)驗(yàn)1、實(shí)驗(yàn)?zāi)康呐c要求:深入理解UDP協(xié)議,掌握API數(shù)據(jù)報(bào)套接字的編程方法,運(yùn)用API相關(guān)函數(shù)實(shí)現(xiàn)UDP協(xié)議,進(jìn)行客戶端與服務(wù)器之間的數(shù)據(jù)通信,分別編寫出客戶端與服務(wù)器端的程序,并調(diào)試運(yùn)行。2、實(shí)驗(yàn)內(nèi)容:兩位同學(xué)各選一臺(tái)網(wǎng)絡(luò)終端,彼此記住對(duì)方的IP地址,約定服務(wù)器的一個(gè)端口號(hào)(大于10000),運(yùn)用Windows API函數(shù)實(shí)現(xiàn)UDP連接,

溫馨提示

  • 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ù)網(wǎng)僅提供信息存儲(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ì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論