版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、<p><b> + </b></p><p> PING和TCP網(wǎng)絡(luò)系統(tǒng)</p><p> Ping命令是使用最頻繁的一個(gè)網(wǎng)絡(luò)測試命令,它能夠測試一個(gè)主機(jī)到另外一個(gè)主機(jī)間的網(wǎng)絡(luò)連接是否連通。在微軟的Windows系統(tǒng)內(nèi)自帶了一個(gè)Ping命令工具,可用于實(shí)現(xiàn)網(wǎng)絡(luò)方面的多個(gè)連接。TCP即文件傳輸協(xié)議,是一種面向鏈接的傳輸層協(xié)議。</p&g
2、t;<p> 在本章的內(nèi)容中,將分別介紹使用C語言開發(fā)一個(gè)類似Windows系統(tǒng)中Ping工具和TCP工具的方法,并詳細(xì)介紹其具體的實(shí)現(xiàn)流程,讓讀者體會(huì)C語言在網(wǎng)絡(luò)編程領(lǐng)域中的應(yīng)用。</p><p> ____________________________________________________________________________________________</p
3、><p><b> 3.1 求職路</b></p><p> 2006年7月2日,酷暑難耐</p><p> 從今天開始,我的學(xué)生生涯就告一段落了。</p><p> 3.1.1 寫求職信</p><p> 2006年7月4日,炎熱的夏天,很多招聘版 </p><p&
4、gt; 不知從何時(shí)起,招聘廣告占據(jù)了主流報(bào)紙的很大版面。我發(fā)現(xiàn)本地的時(shí)報(bào)、晚報(bào)和廣播電視報(bào),都專門推出了招聘版,并且占據(jù)了好幾個(gè)版面。原來工作機(jī)會(huì)多多啊,當(dāng)初還以為畢業(yè)意味著失業(yè),看來我的顧慮是多余的。一大早我買了一份時(shí)報(bào),耐心地瀏覽著招聘信息。</p><p> 看完招聘信息后我失望了,報(bào)紙上自己感興趣的信息很少,即使有也需要兩年以上工作經(jīng)驗(yàn)。真是為難啊,剛剛畢業(yè),何來的工作經(jīng)驗(yàn)?招聘程序員的也不少,但是一
5、看就是小公司,像我這種擁有鴻鵠之志的熱血才子,應(yīng)該去像微軟、Sun等級別的公司才是正道。</p><p> 2006年8月4日,上午,多云間陰</p><p> 不覺間一個(gè)月過去了,工作還是沒有著落,畢業(yè)后待業(yè)在家的感受是很少人能體會(huì)到的。我很頹廢,難道大學(xué)四年的苦讀換來的是這種結(jié)果?我很不甘心。在家人和同學(xué)的鼓勵(lì)下,繼續(xù)開始了我的求職路。</p><p>
6、2006年8月14日,下午,多云間陰,我的簡歷</p><p> 過去的十天,我投了無數(shù)份簡歷,私企、國企、外企,我都嘗試了一遍。在51Job和智聯(lián)招聘等主流招聘網(wǎng)站上,我也投了很多簡歷。簡歷是經(jīng)過我仔細(xì)雕琢之后寫出來的,具體如下。</p><p> (Personal Particulars)</p><p> ———————————————————————
7、————————————————</p><p> 個(gè)人概況 (Personal Data)</p><p> 姓 名:- ×××</p><p> 出生年月:- 1984年11月01號 </p><p> 性 別:- 不告訴你</p><p> 籍 貫:- &
8、#215;××××××</p><p><b> 政治面貌:- 團(tuán)員</b></p><p> 畢業(yè)院校:- ××大學(xué)</p><p> 專 業(yè):- 計(jì)算機(jī)</p><p> 學(xué)歷: - 本科</p><
9、;p> 聯(lián)系方式:- TEL:152×××××××× QQ:3××××××××</p><p> E-mail:- ×××××××@yahoo.com.cn</p
10、><p> ———————————————————————————————————————</p><p> 專業(yè)技能 (Basic Courses)</p><p> 擅長計(jì)算機(jī)維護(hù)、應(yīng)用和開發(fā)。</p><p> 熟悉ASP、PHP、JSP、C、C++、Visual Basic 6.0、C#、JavaScript、HTML、CSS、J
11、ava語言。</p><p> 熟悉Access、SQL Server、MySQL數(shù)據(jù)庫,精通SQL語言。</p><p> 其他:熟悉Dreamweaver、photoshop、CAD、Flash,精通Linux、Unix。</p><p> ———————————————————————————————————————</p><p&g
12、t; 工作經(jīng)歷(Social Practice)</p><p> 2002年6~9月 ××××××××公司(在校兼職) 網(wǎng)站管理員</p><p> 2003年10月~2006年6月 ×××××××
13、×公司 兼職程序員</p><p> ———————————————————————————————————————</p><p> 個(gè)人特質(zhì) (Personal Specialty)</p><p> 性格樂觀,辦事沉穩(wěn),待人誠懇。</p><p> 獨(dú)立能力較強(qiáng),做事大膽細(xì)心,敢于迎接新的挑戰(zhàn)
14、。</p><p> 對工作和朋友始終充滿熱情,思維活躍,有較好的團(tuán)隊(duì)精神。</p><p> 勤奮好學(xué),對新知識有強(qiáng)烈的求知欲。</p><p> ———————————————————————————————————————</p><p> 2006年9月4日,上午,晴空萬里,出師未捷</p><p>
15、 等待應(yīng)聘結(jié)果時(shí)即期盼又害怕,期待自己快點(diǎn)步入職場,也害怕應(yīng)聘失敗。在這種心情下,今天我終于接到了一個(gè)AA公司HR的電話。</p><p> HR:“你好,請問是×××先生嗎?”</p><p><b> 我:“對,我是!”</b></p><p> HR:“你好,我是AA公司的HR!看了您發(fā)的簡歷,很抱歉,
16、我們覺得您不適合我們的這個(gè)崗位。但是我發(fā)現(xiàn)你大學(xué)期間做過不少兼職,我們可以給你一個(gè)來我公司試用的機(jī)會(huì),您看有意向嗎?”</p><p> 我:“我……,我考慮好了再給你們電話吧!”</p><p> 此時(shí)的我心灰意冷,心里暗自問:“我是怎么了?四年的大學(xué)苦讀,畢業(yè)了卻換來這種結(jié)果??!”頓時(shí)對自己的前途沒有了信心。</p><p> 3.1.2 隨遇而安<
17、;/p><p> 2006年9月5日,上午,晴空萬里 </p><p> 我非常失望,無聊的我一直在網(wǎng)絡(luò)上游蕩。在QQ上遇到了大學(xué)老師TC,聽完我的抱怨之后,給了我一條建議:先去AA公司試用,盡量掌握一些項(xiàng)目開發(fā)的技能,也算是提前適應(yīng)一下職場生活,為將來的求職做好準(zhǔn)備。并且對我的簡歷也評價(jià)一番,說簡歷做得很不好,簡歷是步入職場的敲門磚之一,好的簡歷會(huì)增加你求職成功的機(jī)會(huì)。你的這份簡歷給公司
18、HR的印象是:學(xué)得很雜,每門技術(shù)都懂一點(diǎn),但沒有精通一門技術(shù),不適合本公司的任何一個(gè)職位。但是作為一名應(yīng)屆生,懂各項(xiàng)基本的計(jì)算機(jī)技術(shù),有培養(yǎng)前途,所以讓我去試用就不足為奇了。</p><p> 我心想反正現(xiàn)在也是無事可做,去AA公司嘗試一下也未嘗不可。</p><p> 3.2 踏 入 職 場</p><p> 2006年9月10日,萬里無云</p&g
19、t;<p> 今天是一個(gè)特殊的日子,正式宣告我步入職場。雖然只是一個(gè)小小的試用生,但是我也暗下決心努力做好自己的工作。</p><p> AA公司是一個(gè)中型公司,有10個(gè)程序員,5個(gè)軟件工程師,3個(gè)高級軟件工程師。我被分配到了開發(fā)部,為公司內(nèi)正式員工服務(wù),當(dāng)然做得都是底層的活。辦公室內(nèi)成員加我有4個(gè):程序員PrA、程序員PrB、試用生小菜和試用生我。其中小菜是跟我同期被招聘來的。</p&g
20、t;<p> 2006年9月25日,上午,晴空萬里,我的任務(wù)</p><p> 來到公司已有半個(gè)月,我和小菜整天干著公司網(wǎng)站維護(hù)的活,很是無聊。而同辦公室內(nèi)的PrA和PrB都有項(xiàng)目在身,根本無暇關(guān)照我們,只有在午飯時(shí)才會(huì)偶爾侃上幾句。但是,看著他們忙碌的樣子,我很羨慕,希望自己也能夠和他們一樣做項(xiàng)目。</p><p> 經(jīng)過這些日子的相處,我對他們的脾氣和性格也有了一些
21、了解。</p><p><b> 程序員PrA:</b></p><p> 年齡35,從事程序開發(fā)已經(jīng)10余年。性格內(nèi)向,不愛說話,午飯、下班都是獨(dú)來獨(dú)往,真是神龍見首不見尾。開發(fā)經(jīng)驗(yàn)豐富,對事業(yè)無欲無求,最大優(yōu)點(diǎn)是知足常樂。畢業(yè)后就來到AA公司上班,一干10年,沒有突出貢獻(xiàn),也沒有大錯(cuò)誤。</p><p><b> 程序員Pr
22、B:</b></p><p> 年齡28歲,性格活潑外向,愛好廣泛,酷愛體育運(yùn)動(dòng)。大學(xué)畢業(yè)后,來到AA公司試用,試用期過后被公司留用,現(xiàn)已工作3年。很有上進(jìn)心,理想是成為和比爾·蓋茨一樣的軟件巨人。</p><p><b> 試用生小菜:</b></p><p> 和我一樣滿臉稚氣,對未來既充滿渴望,也充滿迷茫。希望
23、試用期過后能被公司留用,并在公司站穩(wěn)腳跟。</p><p> 3.3 第一個(gè)項(xiàng)目</p><p> 2006年10月7日,多云間陰</p><p> 今天是十一假期后的第一天,一大早來到了辦公室。發(fā)現(xiàn)PrB和小菜在辦公桌前嘰嘰喳喳,看到我后趕緊招呼我過去。原來公司準(zhǔn)備考核新人,有一個(gè)簡單的網(wǎng)絡(luò)系統(tǒng)的項(xiàng)目要交給試用生來完成,作為他們的考核?,F(xiàn)在的試用生只有我和
24、小菜,看來這個(gè)項(xiàng)目會(huì)安排給我倆了。</p><p> 3.3.1 我的任務(wù)</p><p> 2006年10月8日,上午,晴空萬里 </p><p> 剛到公司,HR和項(xiàng)目經(jīng)理DP就將我和小菜叫到了辦公室。</p><p> DP:“來公司一個(gè)月了吧,還習(xí)慣吧!現(xiàn)在有一個(gè)考核項(xiàng)目需要你們?nèi)ネ瓿伞狿ING和TCP網(wǎng)絡(luò)系統(tǒng),項(xiàng)目很簡單
25、,要求你們用C語言編程實(shí)現(xiàn)PING和TCP的功能。其中,Bird完成PING模塊,而小菜去完成TCP模塊?!?lt;/p><p> 3.3.2 規(guī)劃流程</p><p> 雖然項(xiàng)目不大,但是事關(guān)我能否通過這個(gè)考核,所以我要好好規(guī)劃一番。圖3-1是我規(guī)劃的進(jìn)展流程圖。</p><p> 圖3-1 進(jìn)展流程圖</p><p> 3.4
26、收 集 資 料</p><p> 2006年10月9日,深夜</p><p> 長夜漫漫,無心睡眠,坐在電腦前,心中想著我的考核項(xiàng)目。根據(jù)我過去開發(fā)項(xiàng)目的經(jīng)驗(yàn),在具體實(shí)施之前,我需要好好規(guī)劃整個(gè)項(xiàng)目,分析出系統(tǒng)所需要的構(gòu)成模塊。本項(xiàng)目系統(tǒng)的構(gòu)成功能模塊如下。</p><p><b> 1.初始化模塊</b></p><
27、p> 用于初始化各個(gè)全局變量,為全局變量賦初始值,初始化Winsock,加載Winsock庫。</p><p><b> 2.控制模塊</b></p><p> 此模塊被其他的模塊調(diào)用,實(shí)現(xiàn)獲取參數(shù)、計(jì)算校驗(yàn)、填充ICMP數(shù)據(jù)報(bào)文、釋放占用資源和顯示用戶幫助。</p><p><b> 3.?dāng)?shù)據(jù)解讀模塊</b>
28、;</p><p> 用于解讀接收到的ICMP報(bào)文和IP選項(xiàng)。</p><p> 4.Ping測試模塊</p><p> 此模塊是本項(xiàng)目實(shí)例的核心模塊,它可以調(diào)用其他的模塊來實(shí)現(xiàn)功能,最終實(shí)現(xiàn)Ping命令功能。</p><p> 上述各模塊的總體結(jié)構(gòu)如圖3-2所示。</p><p> 圖3-2 項(xiàng)目功能模塊
29、結(jié)構(gòu)</p><p> 2006年10月10日,上午,晴空萬里</p><p> 花了一天的時(shí)間,我完成了資料收集工作。很多人對前期的資料收集不屑一顧,認(rèn)為自己水平夠高,編寫一個(gè)項(xiàng)目還不是小菜一碟。但是殊不知世界變化太快,客戶需求也日益拉開。隨時(shí)了解市場變化和新需求,是我們程序員在項(xiàng)目開發(fā)之前必須要做的工作之一,并且一定得做好。</p><p> 3.5 總
30、 體 設(shè) 計(jì)</p><p> 2006年10月10日,下午,微風(fēng)陣陣</p><p> 經(jīng)過前面兩天的忙碌,我明確了項(xiàng)目中需要的功能模塊。接下來的工作就簡單了,我只需根據(jù)規(guī)劃的模塊結(jié)構(gòu)去逐一實(shí)現(xiàn)這些功能即可。</p><p><b> 1.系統(tǒng)運(yùn)行流程</b></p><p> 此系統(tǒng)的運(yùn)行流程如圖3-3所示。
31、</p><p> 圖3-3 系統(tǒng)運(yùn)行流程圖</p><p> 在圖3-3所示的運(yùn)行流程中,將首先調(diào)用InitPing( )函數(shù)來初始化各個(gè)全局變量,然后使用GetArgments函數(shù)來獲取用戶輸入的參數(shù),并檢查用戶輸入的參數(shù),如果參數(shù)不正確,則顯示幫助信息,并結(jié)束程序;如果正確則執(zhí)行Ping命令,顯示結(jié)果并釋放所占用的資源。如果沒有Ping通過則顯示錯(cuò)誤信息,結(jié)束程序。</p
32、><p> 2.GetArgments函數(shù)</p><p> GetArgments函數(shù)用于獲取用戶輸入的參數(shù),在此獲取的參數(shù)有以下3個(gè)。</p><p> -r:記錄路由參數(shù)。</p><p><b> -n:記錄條數(shù)。</b></p><p> Datasize:數(shù)據(jù)報(bào)大小。</p
33、><p> GetArgments函數(shù)的處理流程如下。</p><p> 判斷上述參數(shù)的第一個(gè)字符,如果第一個(gè)字符是“-”,則認(rèn)為是-r或-n中的一個(gè),然后即可進(jìn)行下一步的判斷。</p><p> 如果參數(shù)的第二個(gè)字符是數(shù)字,則判斷此參數(shù)是記錄的條數(shù)。</p><p> 如果第二個(gè)字符是“r”,則判斷該參數(shù)是“-r”,用于記錄路由。<
34、;/p><p> 如果第一個(gè)參數(shù)是數(shù)字,則此參數(shù)是IP或Datasize,然后進(jìn)行下一步判斷。</p><p> 如果參數(shù)中不存在非數(shù)字字符,則此參數(shù)是Datasize;如果存在非數(shù)字字符,則此參數(shù)是IP地址。</p><p> 如果是其他情況,則為主機(jī)名。</p><p> 上述GetArgments函數(shù)的運(yùn)行流程如圖3-4所示。<
35、;/p><p> 圖3-4 GetArgments函數(shù)運(yùn)行流程圖</p><p> 3.函數(shù)Ping處理</p><p> 函數(shù)Ping是本系統(tǒng)的核心,通過調(diào)用其他的函數(shù)來實(shí)現(xiàn)具體功能。函數(shù)Ping可以實(shí)現(xiàn)以下功能。</p><p><b> 創(chuàng)建套接字。</b></p><p><b
36、> 設(shè)置路由選項(xiàng)。</b></p><p> 創(chuàng)建ICMP請求報(bào)文。</p><p> 接收ICMP應(yīng)答報(bào)文。</p><p><b> 解讀ICMP文件。</b></p><p> 2006年10月10日,深夜,體會(huì)總體設(shè)計(jì)</p><p> 現(xiàn)在總體設(shè)計(jì)階段工作完
37、成了。都說總體設(shè)計(jì)很復(fù)雜,其實(shí)總體設(shè)計(jì)是一種科學(xué)的軟件開發(fā)方法??傮w設(shè)計(jì)是指對有關(guān)系統(tǒng)全局問題的設(shè)計(jì),也就是設(shè)計(jì)系統(tǒng)總的處理方案,又稱系統(tǒng)概要設(shè)計(jì)。它包括計(jì)算機(jī)配置設(shè)計(jì)、系統(tǒng)模塊結(jié)構(gòu)設(shè)計(jì)、數(shù)據(jù)庫和文件設(shè)計(jì)、代碼設(shè)計(jì)以及系統(tǒng)可靠性與內(nèi)部控制設(shè)計(jì)等內(nèi)容。作為菜鳥程序員,一定要掌握總體設(shè)計(jì),這樣才能在項(xiàng)目中少走彎路。接下來,就可以進(jìn)入數(shù)據(jù)結(jié)構(gòu)設(shè)計(jì)和函數(shù)規(guī)劃階段了。</p><p> 3.6 設(shè)計(jì)數(shù)據(jù)結(jié)構(gòu)和規(guī)劃函數(shù)&
38、lt;/p><p> 2006年10月11日,微風(fēng)陣陣</p><p> 昨天下午我完成了總體設(shè)計(jì)階段的工作。為了使整個(gè)項(xiàng)目的設(shè)計(jì)思路顯得更加清晰,接下來我將預(yù)先統(tǒng)一規(guī)劃項(xiàng)目中需要的函數(shù),并實(shí)現(xiàn)函數(shù)的定義,這樣在后面的操作中只需編寫函數(shù)的具體實(shí)現(xiàn)代碼即可。</p><p> 3.6.1 設(shè)計(jì)數(shù)據(jù)結(jié)構(gòu)</p><p> 本項(xiàng)目中包含的數(shù)據(jù)
39、結(jié)構(gòu)有如下幾個(gè)。</p><p><b> 1.IP報(bào)頭結(jié)構(gòu)體</b></p><p> 此處的IP報(bào)頭結(jié)構(gòu)體是_iphdr,具體代碼如下。</p><p> typedef struct _iphdr </p><p><b> {</b></p><p> un
40、signed int h_len:4;</p><p> unsigned int version:4;</p><p> unsigned char tos;</p><p> unsigned short total_len;</p><p> unsigned short ident;</p><p
41、> unsigned short frag_flags;</p><p> unsigned char ttl</p><p> unsigned char proto;</p><p> unsigned short checksum;</p><p> unsigned int sourceIP;</p>
42、;<p> unsigned int destIP;</p><p> } IpHeader;</p><p> 在上述結(jié)構(gòu)體_iphdr中,設(shè)置了需要的變量名,各變量的具體說明如下。</p><p> h_len:4:IP報(bào)頭長度。</p><p> version:4:IP的版本號。</p>&l
43、t;p> tos:服務(wù)的類型。</p><p> total_len:數(shù)據(jù)報(bào)總長度。</p><p> ident:唯一的標(biāo)識符。</p><p> frag_flags:分段標(biāo)志。</p><p> proto:協(xié)議類型(TCP、UDP等)。</p><p> checksum:校驗(yàn)和。</p
44、><p> sourceIP:源IP地址。</p><p> destIP:目的IP地址。</p><p> 2.ICMP報(bào)頭結(jié)構(gòu)體</p><p> 此處的ICMP報(bào)頭結(jié)構(gòu)體是_icmphdr,具體代碼如下。</p><p> typedef struct _icmphdr </p><p&
45、gt;<b> {</b></p><p> BYTE i_type; /*ICMP報(bào)文類型*/</p><p> BYTE i_code; /*該類型中的代碼號*/</p><p> USHORT i_cksum; /*校驗(yàn)和*/ </p>
46、;<p> USHORT i_id; /*唯一的標(biāo)識符*/</p><p> USHORT i_seq; /*序列號*/</p><p> ULONG timestamp; /*時(shí)間戳*/ </p><p> } IcmpHeader;&l
47、t;/p><p> i_type結(jié)構(gòu)體表示ICMP報(bào)文類型;i_code表示該類型中的代碼號;i_cksum表示校驗(yàn)和,顏色值可以根據(jù)需要而設(shè)置;i_id表示唯一的標(biāo)識符;i_seq表示序列號;timestamp表示時(shí)間戳。</p><p><b> 3.IP選項(xiàng)結(jié)構(gòu)體</b></p><p> 此處的IP選項(xiàng)結(jié)構(gòu)體是_ipoptionhdr
48、,具體代碼如下。</p><p> typedef struct _ipoptionhdr</p><p><b> {</b></p><p> unsigned char code; /*選項(xiàng)類型*/</p><p> unsigned char len; /
49、*選項(xiàng)頭長度*/</p><p> unsigned char ptr; /*地址偏移長度*/</p><p> unsigned long addr[9]; /*記錄的IP地址列表*/</p><p> } IpOptionHeader;</p><p> 3.6.2 構(gòu)成函數(shù)介紹<
50、/p><p> 2006年10月12日,秋高氣爽</p><p> 昨天的效率非常低,只完成了數(shù)據(jù)結(jié)構(gòu)的設(shè)計(jì)工作。今天我要補(bǔ)上,完成整個(gè)項(xiàng)目的函數(shù)規(guī)劃工作,即根據(jù)系統(tǒng)的需求分析,統(tǒng)一規(guī)劃項(xiàng)目中需要的函數(shù)。此步驟是整個(gè)項(xiàng)目的基礎(chǔ),項(xiàng)目中的具體功能將以此為基礎(chǔ)進(jìn)行擴(kuò)展。</p><p> 1.函數(shù)InitPing</p><p> 函數(shù)Ini
51、tPing用于初始化所需要的變量,具體結(jié)構(gòu)如下:</p><p> void InitPing()</p><p> 2.函數(shù)UserHelp</p><p> 函數(shù)UserHelp用于顯示用戶的幫助信息,具體結(jié)構(gòu)如下:</p><p> void UserHelp()</p><p> 3.函數(shù)GetArg
52、ments</p><p> 函數(shù)GetArgments用于獲取用戶提交的處理參數(shù),具體結(jié)構(gòu)如下:</p><p> void GetArgments(int argc,char** argv)</p><p> 4.函數(shù)CheckSum</p><p> 函數(shù)CheckSum用于計(jì)算校驗(yàn)和,首先把數(shù)據(jù)報(bào)頭中的校驗(yàn)和字段設(shè)置為0,然后
53、對首部中的每個(gè)16bit進(jìn)行二進(jìn)制反碼求和,(即將整個(gè)首部看成是一串16bit的字組成)將結(jié)果存放在校驗(yàn)和字段中。具體結(jié)構(gòu)如下:</p><p> USHORT CheckSum(USHORT *buffer, int size)</p><p> 5.函數(shù)FillICMPData</p><p> 函數(shù)FillICMPData用于填充ICMP數(shù)據(jù)報(bào)字段,其中
54、參數(shù)icmp_data表示ICMP數(shù)據(jù),datasize表示ICMP報(bào)文大小。具體結(jié)構(gòu)如下:</p><p> void FillICMPData(char *icmp_data, int datasize)</p><p> 6.函數(shù)FreeRes</p><p> 函數(shù)FreeRes用于釋放所占用的內(nèi)存資源,具體結(jié)構(gòu)如下:</p><p
55、> void FreeRes()</p><p> 7.函數(shù)DecodeIPOptions</p><p> 函數(shù)DecodeIPOptions用于解讀IP選項(xiàng)頭,從中讀取從源主機(jī)到目標(biāo)主機(jī)經(jīng)過的路由,并輸出路由信息。具體結(jié)構(gòu)如下:</p><p> void DecodeIPOptions(char *buf, int bytes)</p>
56、;<p> 8.函數(shù)DecodeICMPHeader</p><p> 函數(shù)DecodeICMPHeader用于解讀ICMP的報(bào)文信息,其中參數(shù)buf表示存放接收到的ICMP報(bào)文的緩沖區(qū),bytes表示接收到的字節(jié)數(shù),from表示發(fā)送ICMP回顯應(yīng)答的主機(jī)IP地址。具體結(jié)構(gòu)如下:</p><p> void DecodeICMPHeader(char *buf, int
57、 bytes, SOCKADDR_IN *from)</p><p> 9.函數(shù)PingTest</p><p> 函數(shù)PingTest用于進(jìn)行Ping操作處理,具體結(jié)構(gòu)如下:</p><p> void PingTest(int timeout)</p><p> 2006年10月12日,傍晚,C語言數(shù)據(jù)結(jié)構(gòu)的體會(huì)</p>
58、;<p> 現(xiàn)在,我完成了整個(gè)項(xiàng)目的前期工作,接下來我就可以進(jìn)入正式的編碼工作了。過去幾天的忙碌,我意識到了數(shù)據(jù)結(jié)構(gòu)在項(xiàng)目中的重要性。數(shù)據(jù)結(jié)構(gòu)一直是學(xué)習(xí)C語言的難點(diǎn)之一,但是數(shù)據(jù)結(jié)構(gòu)確實(shí)很重要,他包含了整個(gè)項(xiàng)目中需要的數(shù)據(jù)。其實(shí)數(shù)據(jù)結(jié)構(gòu)本身只是一些簡單的理論,讓你知道計(jì)算機(jī)存儲(chǔ)、組織數(shù)據(jù)的方式,了解掌握通用數(shù)據(jù)庫的原理,設(shè)計(jì)通用數(shù)據(jù)庫的理論基礎(chǔ),也可以用于設(shè)計(jì)簡單的小型準(zhǔn)用數(shù)據(jù)庫。C語言是描述數(shù)據(jù)結(jié)構(gòu)中算法的一個(gè)工具,算
59、法必須通過一種語言來實(shí)現(xiàn),現(xiàn)在教材多數(shù)用C或C++語言。要學(xué)好數(shù)據(jù)結(jié)構(gòu),首先要掌握各種結(jié)構(gòu)的基本原理,這些知識必須學(xué)透,然后在掌握一種語言的情況下,會(huì)編寫一些算法,這些算法并不是要死記硬背,而是在理解的前提下編寫。</p><p> 3.7 編 碼 工 作</p><p> 2006年10月13日,陽光明媚</p><p> 經(jīng)過前面幾天的努力,我終于開始具
60、體的編碼工作了。在開始之前,我又看了一遍系統(tǒng)規(guī)劃文件和規(guī)劃函數(shù)。接下來我可以根據(jù)這些資料完成編碼工作。</p><p> 3.7.1 預(yù)處理</p><p> 程序預(yù)處理包括庫文件導(dǎo)入、頭文件加載、定義常量和全局變量,并定義數(shù)據(jù)結(jié)構(gòu)。本項(xiàng)目實(shí)例需要導(dǎo)入的庫文件是“ws2_32.lib”,另外還需要加載頭文件“winsock2.h”和“ws2tcpip.h”。</p>&
61、lt;p> 注意:ws2_32.lib是調(diào)用WinSock2函數(shù)時(shí)需要鏈接的庫文件,即調(diào)用winsock.dll時(shí)的動(dòng)態(tài)鏈接庫,加入此文件就不必要顯示調(diào)用了。</p><p><b> 具體代碼如下所示。</b></p><p><b> /*導(dǎo)入庫文件*/</b></p><p> #pragma comm
62、ent( lib, "ws2_32.lib" )</p><p><b> /*加載頭文件*/</b></p><p> #include <winsock2.h></p><p> #include <ws2tcpip.h></p><p> #include <
63、;stdio.h></p><p> #include <stdlib.h></p><p> #include <math.h></p><p><b> /*定義常量*/</b></p><p> /*表示要記錄路由*/</p><p> #define
64、 IP_RECORD_ROUTE 0x7</p><p> /*默認(rèn)數(shù)據(jù)報(bào)大小*/</p><p> #define DEF_PACKET_SIZE 32 </p><p> /*最大的ICMP數(shù)據(jù)報(bào)大小*/</p><p> #define MAX_PACKET 1024 </p><p> /
65、*最大IP頭長度*/</p><p> #define MAX_IP_HDR_SIZE 60 </p><p> /*ICMP報(bào)文類型,回顯請求*/ </p><p> #define ICMP_ECHO 8</p><p> /*ICMP報(bào)文類型,回顯應(yīng)答*/ </p><p> #define
66、ICMP_ECHOREPLY 0</p><p> /*最小的ICMP數(shù)據(jù)報(bào)大小*/</p><p> #define ICMP_MIN 8</p><p> /*自定義函數(shù)原型*/</p><p> void InitPing();</p><p> void UserHelp();</p>
67、<p> void GetArgments(int argc, char** argv); </p><p> USHORT CheckSum(USHORT *buffer, int size);</p><p> void FillICMPData(char *icmp_data, int datasize);</p><p> void Fre
68、eRes();</p><p> void DecodeIPOptions(char *buf, int bytes);</p><p> void DecodeICMPHeader(char *buf, int bytes, SOCKADDR_IN* from);</p><p> void PingTest(int timeout);</p>
69、<p> /*IP報(bào)頭字段數(shù)據(jù)結(jié)構(gòu)*/</p><p> typedef struct _iphdr </p><p><b> {</b></p><p> unsigned int h_len:4;/*IP報(bào)頭長度*/</p><p> unsigned int version:4
70、;/*IP的版本號*/</p><p> unsigned char tos;/*服務(wù)的類型*/</p><p> unsigned short total_len;/*數(shù)據(jù)報(bào)總長度*/</p><p> unsigned short ident; /*唯一的標(biāo)識符*/</p>
71、<p> unsigned short frag_flags; /*分段標(biāo)志*/</p><p> unsigned char ttl; /*生存期*/</p><p> unsigned char proto; /*協(xié)議類型(TCP、UDP等)*/</p><p>
72、 unsigned short checksum; /*校驗(yàn)和*/</p><p> unsigned int sourceIP; /*源IP地址*/</p><p> unsigned int destIP; /*目的IP地址*/</p><p> } IpHeader;</p><
73、p> /*ICMP報(bào)頭字段數(shù)據(jù)結(jié)構(gòu)*/</p><p> typedef struct _icmphdr </p><p><b> {</b></p><p> BYTE i_type; /*ICMP報(bào)文類型*/</p><p> BYTE i_code;
74、 /*該類型中的代碼號*/</p><p> USHORT i_cksum; /*校驗(yàn)和*/ </p><p> USHORT i_id; /*唯一的標(biāo)識符*/</p><p> USHORT i_seq;
75、/*序列號*/</p><p> ULONG timestamp; /*時(shí)間戳*/ </p><p> } IcmpHeader;</p><p> /*IP選項(xiàng)頭字段數(shù)據(jù)結(jié)構(gòu)*/</p><p> typedef struct _ipoptionhdr</p><p>
76、;<b> {</b></p><p> unsigned char code; /*選項(xiàng)類型*/</p><p> unsigned char len; /*選項(xiàng)頭長度*/</p><p> unsigned char ptr; /*地
77、址偏移長度*/</p><p> unsigned long addr[9]; /*記錄的IP地址列表*/</p><p> } IpOptionHeader;</p><p> /*定義全局變量*/</p><p> SOCKET m_socket;</p><p> IpOpti
78、onHeader IpOption;</p><p> SOCKADDR_IN DestAddr;</p><p> SOCKADDR_IN SourceAddr;</p><p> char *icmp_data;</p><p> char *recvbuf;</p><p> USHORT seq_no
79、;</p><p> char *lpdest;</p><p> int datasize;</p><p> BOOL RecordFlag;</p><p> double PacketNum;</p><p> BOOL SucessFlag;</p><p> 3.7.2
80、 初始化處理</p><p> 初始化需要處理多個(gè)全局變量,并通過WSAStartup函數(shù)來加載Winsock庫。在此需要對icmp_data、recvbuf和lpdest都賦值為null,對seq_no賦值為0,對RecordFlag賦值為DEF_PACKET_SIZE,此處表示默認(rèn)的數(shù)據(jù)報(bào)大小是32。</p><p> 另外,還要對PacketNum賦值為5,5是默認(rèn)記錄,即默認(rèn)發(fā)
81、送5條ICMP回顯請求;對SuccessFlag賦值為False,在程序完全成功執(zhí)行后才會(huì)賦值為True。</p><p> 函數(shù)WSAStartup實(shí)現(xiàn)對Winsock的加載,通過宏MakeWord來獲取準(zhǔn)備加載的Winsock版本。</p><p> 具體實(shí)現(xiàn)的代碼如下所示。</p><p> /*初始化變量函數(shù)*/ </p><p
82、> void InitPing()</p><p><b> {</b></p><p> WSADATA wsaData;</p><p> icmp_data = NULL;</p><p> seq_no = 0;</p><p> recvbuf = NULL;</
83、p><p> RecordFlag = FALSE;</p><p> lpdest = NULL;</p><p> datasize = DEF_PACKET_SIZE;</p><p> PacketNum = 5;</p><p> SucessFlag = FALSE;</p><p
84、> /*Winsock初始化*/</p><p> if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)</p><p><b> {</b></p><p> /*如果初始化不成功則報(bào)錯(cuò),GetLastError()返回發(fā)生的錯(cuò)誤信息*/</p><p>
85、 printf("WSAStartup() failed: %d\n", GetLastError());</p><p><b> return ;</b></p><p><b> }</b></p><p> m_socket = INVALID_SOCKET;</p><
86、;p><b> }</b></p><p> 3.7.3 控制模塊</p><p> 此處控制模塊的功能是為其他模塊提供調(diào)用函數(shù),它能夠?qū)崿F(xiàn)參數(shù)獲取、校驗(yàn)處理、計(jì)算處理、ICMP數(shù)據(jù)填充、釋放占用資源和顯示用戶幫助等功能。具體實(shí)現(xiàn)的代碼如下所示。</p><p> /*顯示信息函數(shù)*/</p><p>
87、 void UserHelp()</p><p><b> {</b></p><p> printf("UserHelp: ping -r <host> [data size]\n");</p><p> printf(" -r record route\n
88、");</p><p> printf(" -n record amount\n");</p><p> printf(" host remote machine to ping\n");</p><p> printf("
89、 datasize can be up to 1KB\n");</p><p> ExitProcess(-1); </p><p><b> }</b></p><p> /*獲取ping選項(xiàng)函數(shù)*/</p><p> void GetArgments(int argc,char*
90、* argv)</p><p><b> {</b></p><p><b> int i;</b></p><p><b> int j;</b></p><p><b> int exp;</b></p><p><
91、;b> int len;</b></p><p><b> int m;</b></p><p> /*如果沒有指定目的地地址和任何選項(xiàng)*/</p><p> if(argc == 1)</p><p><b> {</b></p><p> p
92、rintf("\nPlease specify the destination IP address and the ping option as follow!\n");</p><p> UserHelp();</p><p><b> }</b></p><p> for(i = 1; i < argc;
93、i++)</p><p><b> {</b></p><p> len = strlen(argv[i]);</p><p> if (argv[i][0] == '-')</p><p><b> {</b></p><p> /*選項(xiàng)指示要獲取
94、記錄的條數(shù)*/</p><p> if(isdigit(argv[i][1]))</p><p><b> {</b></p><p> PacketNum = 0;</p><p> for(j=len-1,exp=0;j>=1;j--,exp++)</p><p> /*根據(jù)a
95、rgv[i][j]中的ASCII值計(jì)算要獲取的記錄條數(shù)(十進(jìn)制數(shù))*/</p><p> PacketNum += ((double)(argv[i][j]-48))*pow(10,exp);</p><p><b> }</b></p><p><b> else</b></p><p>&
96、lt;b> {</b></p><p> switch (tolower(argv[i][1]))</p><p><b> {</b></p><p> /*選項(xiàng)指示要獲取路由信息*/</p><p> case 'r': </p><p&g
97、t; RecordFlag = TRUE;</p><p><b> break;</b></p><p> /*沒有按要求提供選項(xiàng)*/</p><p><b> default:</b></p><p> UserHelp();</p><p><b>
98、 break;</b></p><p><b> }</b></p><p><b> }</b></p><p><b> }</b></p><p> /*參數(shù)是數(shù)據(jù)報(bào)大小或者IP地址*/</p><p> else if (
99、isdigit(argv[i][0]))</p><p><b> {</b></p><p> for(m=1;m<len;m++)</p><p><b> {</b></p><p> if(!(isdigit(argv[i][m])))</p><p>
100、<b> {</b></p><p><b> /*是IP地址*/</b></p><p> lpdest = argv[i];</p><p><b> break;</b></p><p><b> }</b></p><
101、p> /*是數(shù)據(jù)報(bào)大小*/</p><p> else if(m==len-1)</p><p> datasize = atoi(argv[i]); </p><p><b> }</b></p><p><b> }</b></p><p> /
102、*參數(shù)是主機(jī)名*/</p><p><b> else</b></p><p> lpdest = argv[i];</p><p><b> }</b></p><p><b> }</b></p><p> /*求校驗(yàn)和函數(shù)*/</p
103、><p> USHORT CheckSum(USHORT *buffer, int size)</p><p><b> {</b></p><p> unsigned long cksum=0;</p><p> while (size > 1) </p><p><b>
104、 {</b></p><p> cksum += *buffer++;</p><p> size -= sizeof(USHORT);</p><p><b> }</b></p><p> if (size) </p><p><b> {</b>&
105、lt;/p><p> cksum += *(UCHAR*)buffer;</p><p><b> }</b></p><p> /*對每個(gè)16bit進(jìn)行二進(jìn)制反碼求和*/</p><p> cksum = (cksum >> 16) + (cksum & 0xffff);</p>
106、<p> cksum += (cksum >>16);</p><p> return (USHORT)(~cksum);</p><p><b> }</b></p><p> /*填充ICMP數(shù)據(jù)報(bào)字段函數(shù)*/</p><p> void FillICMPData(char *icmp
107、_data, int datasize)</p><p><b> {</b></p><p> IcmpHeader *icmp_hdr = NULL;</p><p> char *datapart = NULL;</p><p> icmp_hdr = (IcmpHeader*)icmp_data;<
108、/p><p> /*ICMP報(bào)文類型設(shè)置為回顯請求*/</p><p> icmp_hdr->i_type = ICMP_ECHO; </p><p> icmp_hdr->i_code = 0;</p><p> /*獲取當(dāng)前進(jìn)程IP作為標(biāo)識符*/</p><p> icmp_hdr-
109、>i_id = (USHORT)GetCurrentProcessId();</p><p> icmp_hdr->i_cksum = 0;</p><p> icmp_hdr->i_seq = 0;</p><p> datapart = icmp_data + sizeof(IcmpHeader);</p><p>
110、; /*以數(shù)字0填充剩余空間*/</p><p> memset(datapart,'0',datasize-sizeof(IcmpHeader));</p><p><b> }</b></p><p> /*釋放資源函數(shù)*/</p><p> void FreeRes()</p>
111、<p><b> {</b></p><p> /*關(guān)閉創(chuàng)建的套接字*/</p><p> if (m_socket != INVALID_SOCKET) </p><p> closesocket(m_socket);</p><p> /*釋放分配的內(nèi)存*/</p><p&
112、gt; HeapFree(GetProcessHeap(), 0, recvbuf);</p><p> HeapFree(GetProcessHeap(), 0, icmp_data);</p><p> /*注銷WSAStartup()調(diào)用*/</p><p> WSACleanup();</p><p><b> r
113、eturn ;</b></p><p><b> }</b></p><p> 3.7.4 數(shù)據(jù)報(bào)解讀處理</p><p> 此處控制模塊的功能是解讀IP選項(xiàng)和ICMP報(bào)文,當(dāng)主機(jī)接收到目的主機(jī)返回的ICMP回顯應(yīng)答后,就調(diào)用ICMP解讀函數(shù)來解讀ICMP報(bào)文,并且ICMP解讀函數(shù)將調(diào)用IP選項(xiàng)解讀函數(shù)來實(shí)現(xiàn)IP路由輸出。具
114、體實(shí)現(xiàn)的代碼如下所示。</p><p> /*解讀IP選項(xiàng)頭函數(shù)*/</p><p> void DecodeIPOptions(char *buf, int bytes)</p><p><b> {</b></p><p> IpOptionHeader *ipopt = NULL;</p>&
115、lt;p> IN_ADDR inaddr;</p><p><b> int i;</b></p><p> HOSTENT *host = NULL;</p><p> /*獲取路由信息的地址入口*/</p><p> ipopt = (IpOptionHeader *)(buf + 20);</
116、p><p> printf("RR: ");</p><p> for(i = 0; i < (ipopt->ptr/4) - 1; i++)</p><p><b> {</b></p><p> inaddr.S_un.S_addr = ipopt->addr[i];&l
117、t;/p><p> if (i != 0)</p><p> printf(" ");</p><p> /*根據(jù)IP地址獲取主機(jī)名*/</p><p> host = gethostbyaddr((char *)&inaddr.S_un.S_addr,sizeof</p><p&
118、gt; (inaddr.S_un.S_addr), AF_INET);</p><p> /*如果獲取到了主機(jī)名,則輸出主機(jī)名*/</p><p><b> if (host)</b></p><p> printf("(%-15s) %s\n", inet_ntoa(inaddr), host->h_name
119、);</p><p> /*否則輸出IP地址*/</p><p><b> else</b></p><p> printf("(%-15s)\n", inet_ntoa(inaddr));</p><p><b> }</b></p><p>&
120、lt;b> return;</b></p><p><b> }</b></p><p> /*解讀ICMP報(bào)頭函數(shù)*/</p><p> void DecodeICMPHeader(char *buf, int bytes, SOCKADDR_IN *from)</p><p><b&g
121、t; {</b></p><p> IpHeader *iphdr = NULL;</p><p> IcmpHeader *icmphdr = NULL;</p><p> unsigned short iphdrlen;</p><p> DWORD tick;</p><p> stati
122、c int icmpcount = 0;</p><p> iphdr = (IpHeader *)buf;</p><p> /*計(jì)算IP報(bào)頭的長度*/</p><p> iphdrlen = iphdr->h_len * 4;</p><p> tick = GetTickCount();</p><p&
123、gt; /*如果IP報(bào)頭的長度為最大長度(基本長度是20字節(jié)),則認(rèn)為有IP選項(xiàng),需要解讀IP選項(xiàng)*/</p><p> if ((iphdrlen == MAX_IP_HDR_SIZE) && (!icmpcount))</p><p> /*解讀IP選項(xiàng),即路由信息*/</p><p> DecodeIPOptions(buf, byte
124、s);</p><p> /*如果讀取的數(shù)據(jù)太小*/</p><p> if (bytes < iphdrlen + ICMP_MIN) </p><p><b> {</b></p><p> printf("Too few bytes from %s\n", </p>
125、<p> inet_ntoa(from->sin_addr));</p><p><b> }</b></p><p> icmphdr = (IcmpHeader*)(buf + iphdrlen);</p><p> /*如果收到的不是回顯應(yīng)答報(bào)文則報(bào)錯(cuò)*/</p><p> if (icm
126、phdr->i_type != ICMP_ECHOREPLY) </p><p><b> {</b></p><p> printf("nonecho type %d recvd\n", icmphdr->i_type);</p><p><b> return;</b></p
127、><p><b> }</b></p><p> /*核實(shí)收到的ID號和發(fā)送的是否一致*/</p><p> if (icmphdr->i_id != (USHORT)GetCurrentProcessId()) </p><p><b> {</b></p><p&g
128、t; printf("someone else's packet!\n");</p><p><b> return ;</b></p><p><b> }</b></p><p> SucessFlag = TRUE;</p><p> /*輸出記錄信息*/
129、</p><p> printf("%d bytes from %s:", bytes, inet_ntoa(from->sin_addr));</p><p> printf(" icmp_seq = %d. ", icmphdr->i_seq);</p><p> printf(" time:
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 眾賞文庫僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 淺談涉密網(wǎng)絡(luò)系統(tǒng)布線和施工
- 1校網(wǎng)絡(luò)系統(tǒng)
- 工廠網(wǎng)絡(luò)系統(tǒng)規(guī)劃
- 混沌系統(tǒng)和復(fù)雜網(wǎng)絡(luò)系統(tǒng)的控制、同步和演化研究.pdf
- ping命令檢測網(wǎng)絡(luò)連接
- 電力通信網(wǎng)絡(luò)系統(tǒng)設(shè)計(jì)和研究.pdf
- 汽車can網(wǎng)絡(luò)系統(tǒng)試驗(yàn)
- GSM網(wǎng)絡(luò)系統(tǒng)優(yōu)化.pdf
- 網(wǎng)絡(luò)系統(tǒng)集成技術(shù)
- 織物CAD網(wǎng)絡(luò)系統(tǒng).pdf
- 副詞“還”語義網(wǎng)絡(luò)系統(tǒng)的形成和發(fā)展.pdf
- P-TDMA-SYS:基于TCP-IP的戰(zhàn)術(shù)TDMA網(wǎng)絡(luò)系統(tǒng)設(shè)計(jì)及其實(shí)現(xiàn).pdf
- ping和ipconfig命令詳解
- 片上網(wǎng)絡(luò)系統(tǒng)模型.pdf
- 大廈網(wǎng)絡(luò)系統(tǒng)畢業(yè)論文
- 商品展示網(wǎng)絡(luò)系統(tǒng)設(shè)計(jì).pdf
- 遠(yuǎn)程視頻監(jiān)控網(wǎng)絡(luò)系統(tǒng).pdf
- 財(cái)政局網(wǎng)絡(luò)系統(tǒng)方案
- 第1章 網(wǎng)絡(luò)系統(tǒng)緒論
- 基于以太網(wǎng)TCP-IP協(xié)議的智能樓宇控制網(wǎng)絡(luò)系統(tǒng)研究與開發(fā).pdf
評論
0/150
提交評論