CC++編程答疑解惑_第1頁
CC++編程答疑解惑_第2頁
CC++編程答疑解惑_第3頁
CC++編程答疑解惑_第4頁
CC++編程答疑解惑_第5頁
已閱讀5頁,還剩283頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、C/C+編程答疑解惑1.C/C+編程1.1: 遇到問題怎么解決 A 論壇的精華區(qū)也有相應(yīng)的討論,許多可以直接解決你的問題,也可以GOOGLE查找,并看看精華區(qū)。 如果已找了GOOGLE并看了精華區(qū),但是對某些方面不理解,那么就在論壇上發(fā)問。發(fā)問時標題要清楚,并把你的問題描述清楚。許多人不會看你帖子的內(nèi)容,所以在標題中寫清楚問題也是很重要的。 如果要粘貼代碼,那么使用發(fā)言功能中的CODE功能,這樣可以保證代碼不會亂,能有更多人看懂你代碼。 當別人準確回答了你的問題時,應(yīng)該說聲謝謝,表示這個問題已回答,并表示對幫助你的人的感謝。這樣會讓更多的人覺得你的一個好學(xué)有禮貌的人,從而會更注意你的問題。 如

2、果你按上面這些方法做了,并不能保證你的發(fā)言一定能回答,因為不是每個人什么問題都知道,但可以保證會有更多人關(guān)注你的問題,回答的可能性會更高。 1.2:STL string 怎么轉(zhuǎn)換大小寫 A:使用STL算法中的transform 函數(shù) 代碼:   string str22 = "This IS a MiXed CaSE stRINg"    transform (str22.begin(),str22.end(), str22.begin(), tolower); 1.3: 怎樣生成動態(tài)庫 A:創(chuàng)建步驟: 首先創(chuàng)建object文件,這個

3、文件將加入通過gcc fPIC 參數(shù)命令加入到共享函數(shù)庫里面。PIC的意思是“位置無關(guān)代碼”(Position Independent Code)。下面是一個標準的格式: 代碼:gcc -shared -Wl,-soname,your_soname -o library_name file_list library_list 下面再給一個例子,它創(chuàng)建兩個object文件(a.o和b.o),然后創(chuàng)建一個包含a.o和b.o的共享函數(shù)庫。例子中”-g”和“Wall”參數(shù)不是必須的。 代碼:gcc -fPIC -g -c -Wall a.c gcc -fPIC -g -c -Wall b.c gcc

4、-shared -Wl,-soname,liblusterstuff.so.1 -o liblusterstuff.so.1.0.1 a.o b.o -lc 下面是一些需要注意的地方: · 不用使用-fomit-frame-pointer這個編譯參數(shù)除非你不得不這樣。雖然使用了這個參數(shù)獲得的函數(shù)庫仍然可以使用,但是這使得調(diào)試程序幾乎沒有用,無法跟蹤調(diào)試。 · 使用-fPIC來產(chǎn)生代碼。 使用shared 說明生成動態(tài)庫,使用soname說明生成的庫名 · 某些情況下,使用gcc 來生成object文件,需要使用“-Wl,-export-dynamic”這個選項參數(shù)

5、。通常,動態(tài)函數(shù)庫的符號表里面包含了這些動態(tài)的對象的符號。這個選項在創(chuàng)建ELF格式的文件時候,會將所有的符號加入到動態(tài)符號表中。可以參考ld的幫助獲得更詳細的說明。 star3s補充: 對于C+程序要使用EXTERN “C”說明輸出接口 代碼:   extern "C"          int soTest(int a,int b) ;        int soTest(int a,int b)         

6、 return a+b;     1.4:怎樣指定程序鏈接某個庫的動態(tài)庫或靜態(tài)庫版本 A:使用Bdynamic和-Bstatic選項。默認情況下,假如共享庫可用,連接器會使用共享庫。但是-Bdynamic和-Bstatic提供了很好控制庫的方法。它們可以決定用共享庫還是用靜態(tài)庫。 傳-Bdynamic和-Bstatic選項給連接器,如下操作: # gcc -o main main.o -Wl,-Bstatic -lfoo -Wl,-Bdynamic -lbar # gcc -o main main.o -Wl,-Bstatic 告訴連接器所有的庫(象libc等等)都使用靜態(tài)

7、的版本。 1.5: 請問各UNIX平臺下和編譯器名 kaisakaisa : sun CC (c+) cc(c) alpha cxx(c+) cc(c) HP aCC(c+) IBM xlC (c+) 1.6: solaris下有沒有C函數(shù)可以獲得進程的相關(guān)信息 比如:進程名、進程pid、進程所占CPU/Memory、開始時間、運行狀態(tài)等等。謝謝。 liupch:2003-03-19 10:03 讀取/proc/進程號/psinfo這個文件。 就用我告訴你的那個函數(shù) ioctl(fd, PIOCPSINFO, &procinfo); 在看一下procinfo這個結(jié)構(gòu)就知道了。 1.7:

8、 c+下使用<iostream>的問題 在c+下使用include <iostream>后為什么編譯器會報錯呢 1.檢查你是不是使用g+編譯器編譯。gcc編c+程序會有問題 2.檢查在include 頭文件后有沒有使用using namespace std; 新的標準C+加了幾個關(guān)鍵字,其中最常用的就是namespace(名字空間) 加入這個關(guān)鍵字是為了避免在大程序中符號名重定義問題 同時原來的標準c+類都包含在std 名字空間中(如果使用c+ 的標準函數(shù)庫,如<cstdio> 那么它們也在std名字空間中) 新的標準c+頭文件沒有 .h,所以當你們incl

9、ude它們時要注意使用std名字空間. 以下一個例子 代碼:#nclude <iostream> #include <string> using namespace std;  /在include 所有標準c+頭文件后 main()     cout<<"hello world"<<endl; 1.8 :volatile的作用是什么 volatile的本意是“易變的” 由于訪問寄存器的速度要快過RAM,所以編譯器一般都會作減少存取外部RAM的優(yōu)化。 一般說來,volatile用在如下的幾個地方:

10、1、中斷服務(wù)程序中修改的供其它程序檢測的變量需要加volatile; 2、多任務(wù)環(huán)境下各任務(wù)間共享的標志應(yīng)該加volatile; 3、存儲器映射的硬件寄存器通常也要加volatile說明,因為每次對它的讀寫都可能由不同意義; 另外,以上這幾種情況經(jīng)常還要同時考慮數(shù)據(jù)的完整性(相互關(guān)聯(lián)的幾個標志讀了一半被打斷了重寫),在1中可以通過關(guān)中斷來實現(xiàn),2中可以禁止任務(wù)調(diào)度,3中則只能依靠硬件的良好設(shè)計了。 簡單點: 就是該變量會以編譯器無法預(yù)知的方式發(fā)生變化,請編譯器不要做優(yōu)化(所有的編譯器的優(yōu)化均假設(shè)編譯器知道變量的變化規(guī)律) 1.9: 請問,用 gcc 或 ld 連接程序時,如何設(shè)置段的屬性? 幽

11、靈兵: 為了實現(xiàn)共享數(shù)據(jù),這個方法要比其它 進程/線程 的數(shù)據(jù)同步方法更 快,更方便,更靈活,而且是所有方法中最簡單的。 比如我在 Win 下這樣做: 1. 創(chuàng)建個 DLL 專門用于數(shù)據(jù)交換 2. 在 DLL 中聲明一個全局變量 Var1 3. 在連接時聲明 .bss 段為共享段 ( Vc Linker: /section:.bss,S | Gcc: type Var1 _attrbiute_ (section("shared"), shared); ) 4. 在需要這個變量的進程中調(diào)用這個 DLL . . 其實就是將這個DLL作為一種數(shù)據(jù)池. 難道你們沒用過嗎? 我想將

12、.bss 段設(shè)置為 共享,gcc 在 NT 下可以用: int Var _attrbiute_ (section("shared"), shared); 在 Linux/UNIX 下怎么辦呢? JohnBull :2003-04-27 Linux系統(tǒng)并不強調(diào)“段”的使用,因為Linux的設(shè)計者考慮到這個OS將移植到包括RISC等多種平臺上,而事實上只有Intel的CPU才強調(diào)“段”的概念,其他(包括大多數(shù)64位)系統(tǒng)都是基于“頁”進行設(shè)計的。 在Linux中,請用共享內(nèi)存。 2.數(shù)據(jù)庫編程2.1:如何在pro*c中調(diào)用存儲過程 ilmare : 在嵌入式SQL中使用CALL

13、 語句調(diào)用存儲過程的格式如下: 代碼:EXEC SQL CALL schema. package. stored_procdb_link (arg1, .) INTO :ret_var INDICATOR :ret_ind; 例子: 創(chuàng)建一個PL/SQL函數(shù)fact,該函數(shù)存儲于mathpkg包中 代碼:EXEC SQL CREATE OR REPLACE PACKAGE BODY mathpkg as function fact(n IN INTEGER) RETURN INTEGER AS BEGIN IF (n <= 0) then return 1; ELSE return n

14、* fact(n - 1); END IF; END fact; END mathpkg; END-EXEC. 使用該函數(shù) . int num, fact; . EXEC SQL CALL mathpkg.fact(:num) INTO :fact; . 2.2: 請問在pro*c中知道錯誤代碼,怎么查這個代碼的錯誤信息? mengwg : 在sql*plus中使用>oerr ora 1013 CHUJUN_98: sqlca中含有中文含義 sqlca.sqlerrm.sqlerrmc代表的是sqlCZHI行的結(jié)果描述 2.3: AIX下編譯的嵌入式DB2 C程序,刪除數(shù)據(jù)庫后再創(chuàng)建時連

15、接不成功 預(yù)編譯:embprep proc 得到proc.bnd和proc.c文件,編譯沒有錯誤發(fā)生。 編譯:xlc -o proc proc.c -ldb2 編譯正確,生成執(zhí)行文件proc。 執(zhí)行proc一切正常。 因為涉及到可能的移植問題,于是測試將數(shù)據(jù)庫Emp Drop掉(db2 drop database Emp),再重新建原來相同的數(shù)據(jù)庫Emp和表info,建成后執(zhí)行proc,程序可正常連接數(shù)據(jù)庫,可在對表info操作時(如select)返回SQLCODE錯誤=-805,也就是說無法對表進行操作。重新編譯該程序后,運行正常! AIX 下的DB2數(shù)據(jù)庫不太好用,它在編譯時會產(chǎn)生一個PK

16、G存放于數(shù)據(jù)庫中, 并且會對它打上時間戳。如果從新建庫獲建表的話都會破壞時間戳,必須從新編譯或rebind,以產(chǎn)生新的PKG。 hasjing:2003-03-17 12:55 AIX 下的DB2數(shù)據(jù)庫不太好用,它在編譯時會產(chǎn)生一個PKG存放于數(shù)據(jù)庫中, 并且會對它打上時間戳。如果從新建庫獲建表的話都會破壞時間戳,必須從新編譯或rebind,以產(chǎn)生新的PKG。 時間戳的目的是為了保證db2數(shù)據(jù)庫優(yōu)化策略的一致性,而且PKG的內(nèi)部名稱 是SQC文件的前八個字母,所以在開發(fā)時要當心每個模塊的名字前八個字母不能相同!否則會產(chǎn)生PKG覆蓋,會產(chǎn)生818的錯誤代碼! 所以IBM的東西雖好,但是規(guī)矩太多!

17、 在db2環(huán)境下 ? SQL0805 可以查看錯誤代碼! 2.4: 請問SOLARIS下使用OCI編程序要連什么庫 在Solaris8下安裝了oracle8.1.6,并編譯用OCI編寫的程序,其中使用了很多的oci函數(shù),包括Direct Path API,但聯(lián)接時,提示OCIDirPathColArrayReset'等符號找不到 編譯時已加入了-L/export/home/opt/oracle/8.1.6/lib -lclntsh 如果將Direct Path的調(diào)用去掉,則連接成功,請各位高手不吝賜教 wangz :2003-03-20 加上-lclient8就可以了!試試看,我這里可

18、以 2.5:請問怎樣用ct-librery編程 有哪位熟悉ct-library編程,我在寫有關(guān)socket通訊的程序,需要和sybase數(shù)據(jù)庫交互信息。希望和高手切磋一下! minsanyuan :2003-04-21 22:55 調(diào)CT-Library就可以了,那來的socket呀, 如果用socket就不要用ct-Library了, 如果你很牛,可以試試兩都都用 1. 初始化ct-library ct_init( .) 2. 分配連接結(jié)構(gòu) ct_con_alloc(.) 3. 設(shè)置用戶名及口令 ct_con_props(.) 4. 建立連接 ct_connect(.) 5. 斷開連接 ct

19、_exit( . ) 6. 釋放 ct_ctx_drop(.) /Sybase/sample下有例子 3 GTK+ 編程 以下由付強提供,QQ:775341 ,感謝他把自己的學(xué)習(xí)成果寫出來與大家分享 原作者聲明如下 > 這些文章其實是我的學(xué)習(xí)筆記,以 FAQ方式代問自答,希 > 望能幫初學(xué)者解決一點實際問題。 > 您可以隨意修改或轉(zhuǎn)載本文,但請保證內(nèi)容的正確性,以 > 免誤人子弟 - 謝謝 :) 3.1問:論壇中有人說 GTK+ 并不支持中文,是這樣嗎? - 答: GTK+ 采用 UTF-8 編碼就是為了支持多字節(jié)文字,所以GTK+ 肯定支持中文,而且非常出色,你可以看

20、到網(wǎng)上使用 GTK+ 編寫 的中文軟件數(shù)不勝數(shù),所以沒必要理會那種說法。 ( 我真的看過這類的帖子,誤人子弟.呵呵. ) >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 3.

21、2問:為什么在控件上的漢字無法顯示,并伴有如下錯誤警告: "* (:1864): WARNING *: Invalid UTF8 string passed to pango_layout_set_text()" - 答: GTK+ 中的字符串均采用 UTF-8 格式編碼,這個提示就是告 訴您,程序中的字符串編碼格式不是 UTF-8,通常這是由編輯器 造成的,例如在我的 VC7 中,默認的存檔編碼格式為 GB2312。 但是,除了將文件以 UTF-8編碼格式存檔外,你還可以使用 glib 的轉(zhuǎn)換函數(shù)在程序的運行過程中將字符串轉(zhuǎn)換為 UTF-8。 例如: 將 button =

22、 gtk_button_new_with_label( "確定" ); 改成 button = gtk_button_new_with_label( g_locale_to_utf8("確定",4,NULL,NULL,NULL); >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

23、>>>>>>>>>>>>>>>>>> 3.3問:為什么在屏幕上輸出的漢字變成了亂碼? - 答: 既然可以顯示亂碼,就表明與編碼格式無關(guān)。 您可能已經(jīng)想到了 - 對,問題就出在字體上。 一般情況下,系統(tǒng)會用"Sans"作為默認字體,但這種字體中 只包含了 ASCII 碼,所以漢字是無法顯示的。 >>>>>>>>>>>>>>>>>>>>>>&

24、gt;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 3.4問: 在修改控件字體的第一步就發(fā)生了錯誤,gdk_font_load() 總是失敗,為什么? - 答: 首先向您提供一些建議: 1.不要用 GDK 的一些函數(shù)更改字體,因為那是 GTK+的不穩(wěn)定 因素之一(至少在2.0以下版本中是這樣的)。 2.為了獲得更多的字體,應(yīng)該避免使用 GdkFont類型

25、,及相關(guān) 函數(shù),取而代之的是 Pango 庫,這是 GTK+ 的一部分。 3.GdkFont 只能使用 XFont 字體,而且使用方法相對復(fù)雜, PangoFontDescription 可以使用 XFont,以及一些本地字體, 包括 Win Font, XRender Font, TrueType Font,所以您沒有必 要再留戀 GdkFont 了。 4.您不需要修改所有控件,更簡便的方法是在主窗口創(chuàng)建后立 即修改它的字體,將來創(chuàng)建的控件會繼承它的這項屬性。 例如: 代碼:window = gtk_window_new( GTK_WINDOW_TOPLEVEL ); GtkStyle *s

26、tyle = gtk_rc_get_style( window ); pango_font_description_set_family( style->font_desc, "Stsong" ); gtk_widget_set_style( window, style ); ( 這三句代碼是將程序的字體設(shè)置為 "華文宋體" ) >>>>>>>>>>>>>>>>>>>>>>>>>>>>

27、;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 3.5問:我不想使用宋體,怎樣獲得其它字體的代號? - 答: 部分字體的代號和它的文件名是相同的,例如黑體的代碼為 "Simhei",華文宋體為"Stsong"。 您還可以通過一些 Linux/Unix 下的編輯軟件的字體選擇框 來查找字體對應(yīng)的代碼。 但標準的方法是調(diào)用 Pango庫中的相應(yīng)函數(shù)來查找機器

28、上已 安裝的字體。 如果想了解更多關(guān)于 Pango的高級使用方法,請參考它自帶 的 API 開發(fā)手冊。 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 3.6問:你為什么沒有

29、說到 gettext() 及相關(guān)國際化標準? 答: 目前國內(nèi)多數(shù)程序員采用這個辦法漢化程序,所以我沒有必 要再多說。但它不一定對每個人都合適,我通常采用自己管理語 言模塊的方法實現(xiàn)國際化,這在很多情況下要比 gettext()更方 便。 4. 系統(tǒng)編程 4.1 我建立共享內(nèi)存之后,忘記了刪除掉。請問:1)如果我不管它,它是由系統(tǒng)自己釋放掉么 一顆流星: 我建立共享內(nèi)存之后,忘記了刪除掉。請問:1)如果我不管它,它是由系統(tǒng)自己釋放掉么?那么系統(tǒng)管理共享內(nèi)存的機制是怎樣的? 2)能否手動釋放?如果能,用什么語句呢? gadfly :2003-04-11 不會自動釋放,可以用ipcrm刪掉 藍色鍵盤

30、:2003-04-18 用shmctl或者ipcrm刪除后,只有如下情況出現(xiàn)才會被徹底清除。 *直到最后一個連接進程釋放它* 或者 *沒有一個進程在attach它* 4.2 請問IPCS顯示的各權(quán)限位意義 一顆流星: C表示具有什么存取權(quán)? 藍色鍵盤:2003-04-18 ipcs顯示的結(jié)果中 標志位是共有11位。其中前兩位表示如下: R 表示進程等待msgrcv S 表示進程等待msgsnd D 表明該段IPC資源已經(jīng)被刪除,直到最后一個連接進程釋放它(請注意這一點,很多情況下往往無法用ipcrm正常刪除IPC資源,原因就在于此) C 在進程attach時,共享內(nèi)存段已經(jīng)被清除 - 相應(yīng)的權(quán)

31、限沒有被設(shè)置 其它的9位表明該段IPC資源的權(quán)限信息。這個大家都明白,但是注意 - 表明指定權(quán)限沒有被設(shè)置。 4.3 如何在unix下實現(xiàn)kbhit的功能?謝謝! clilye:如何在unix下實現(xiàn)kbhit的功能?謝謝! fieryfox: 2003-04-29 下面的文字摘自Unix Programming FAQ: 3.2 How can I read single characters from the terminal? = How can I read single characters from the terminal? My program is always waiting

32、 for the user to press <RETURN>'. Terminals are usually in canonical mode, where input is read in lines after it is edited. You may set this into non-canonical mode, where you set how many characters should be read before input is given to your program. You also may set the timer in non-ca

33、nonical mode terminals to 0, this timer flushs your buffer at set intervals. By doing this, you can use getc()' to grab the key pressed immediately by the user. We use tcgetattr()' and tcsetattr()' both of which are defined by POSIX to manipulate the termios' structure. #include <

34、stdlib.h> #include <stdio.h> #include <termios.h> #include <string.h> static struct termios stored; void set_keypress(void) struct termios new; tcgetattr(0,&stored); memcpy(&new,&stored,sizeof(struct termios); /* Disable canonical mode, and set buffer size to 1 byte

35、*/ new.c_lflag &= (ICANON); new.c_ccVTIME = 0; new.c_ccVMIN = 1; tcsetattr(0,TCSANOW,&new); return; void reset_keypress(void) tcsetattr(0,TCSANOW,&stored); return; 3.3 How can I check and see if a key was pressed? = How can I check and see if a key was pressed? On DOS I use the kbhit()&#

36、39; function, but there doesn't seem to be an equivalent? If you set the terminal to single-character mode (see previous answer), then (on most systems) you can use select()' or poll()' to test for readability. 5. Solaris內(nèi)核編程相關(guān)問題 5.1 Solaris內(nèi)核模塊中如何getcwd Q: 在Solaris 7 64-bit內(nèi)核模塊中如何獲知一個進程

37、的當前工作目錄(cwd),getcwd 并不是一個系統(tǒng)調(diào)用 A: Rich Teer <richrite-> 最好通過u->u_cdir獲取當前工作目錄(cwd)的vnode(v節(jié)點)。但這依賴于內(nèi)核當前上 下文,curproc可能并不對應(yīng)你期望的進程。 代碼:usr/include/sys/user.h typedef struct user . . /* * protected by p_lock */ struct vnode * u_cdir; /* current directory */ struct vnode * u_rdir; /* root directo

38、ry */ 5.2 如何避免一個套接字進入TIME_WAIT狀態(tài) Q: 我正在寫一個unix server程序,不是daemon,經(jīng)常需要在命令行上重啟它,絕大 多數(shù)時候工作正常,但是某些時候會報告"bind: address in use",于是重啟失 敗。 A: Andrew Gierth <andrewerlenstar.demon.co.uk> server程序總是應(yīng)該在調(diào)用bind()之前設(shè)置SO_REUSEADDR套接字選項。至于 TIME_WAIT狀態(tài),你無法避免,那是TCP協(xié)議的一部分。 Q: 如何避免等待60秒之后才能重啟服務(wù) A: Erik

39、Max Francis <max> 使用setsockopt,比如 代碼:-  int option = 1;  if ( setsockopt ( masterSocket, SOL_SOCKET, SO_REUSEADDR, &option,                    sizeof( option ) ) < 0 )        die( "setsockopt" );&#

40、160;   -  5.3編寫 TCP/SOCK_STREAM 服務(wù)程序時,SO_REUSEADDR到底什么意思? A: 這個套接字選項通知內(nèi)核,如果端口忙,但TCP狀態(tài)位于 TIME_WAIT ,可以重用 端口。如果端口忙,而TCP狀態(tài)位于其他狀態(tài),重用端口時依舊得到一個錯誤信息, 指明"地址已經(jīng)使用中"。如果你的服務(wù)程序停止后想立即重啟,而新套接字依舊 使用同一端口,此時 SO_REUSEADDR 選項非常有用。必須意識到,此時任何非期 望數(shù)據(jù)到達,都可能導(dǎo)致服務(wù)程序反應(yīng)混亂,不過這只是一種可能,事實上很不 可能。 一個套接字由相關(guān)五元組構(gòu)成,協(xié)議、

41、本地地址、本地端口、遠程地址、遠程端 口。SO_REUSEADDR 僅僅表示可以重用本地本地地址、本地端口,整個相關(guān)五元組 還是唯一確定的。所以,重啟后的服務(wù)程序有可能收到非期望數(shù)據(jù)。必須慎重使 用 SO_REUSEADDR 選項。 5.4在客戶機/服務(wù)器編程中(TCP/SOCK_STREAM),如何理解TCP自動機 TIME_WAIT 狀 態(tài)? A: W. Richard Stevens <1999年逝世,享年49歲> 下面我來解釋一下 TIME_WAIT 狀態(tài),這些在<<Unix Network Programming Vol I>> 中2.6節(jié)解釋很清

42、楚了。 MSL(最大分段生存期)指明TCP報文在Internet上最長生存時間,每個具體的TCP實現(xiàn) 都必須選擇一個確定的MSL值。RFC 1122建議是2分鐘,但BSD傳統(tǒng)實現(xiàn)采用了30秒。 TIME_WAIT 狀態(tài)最大保持時間是2 * MSL,也就是1-4分鐘。 IP頭部有一個TTL,最大值255。盡管TTL的單位不是秒(根本和時間無關(guān)),我們?nèi)孕?假設(shè),TTL為255的TCP報文在Internet上生存時間不能超過MSL。 TCP報文在傳送過程中可能因為路由故障被迫緩沖延遲、選擇非最優(yōu)路徑等等,結(jié)果 發(fā)送方TCP機制開始超時重傳。前一個TCP報文可以稱為"漫游TCP重復(fù)報文&q

43、uot;,后一個 TCP報文可以稱為"超時重傳TCP重復(fù)報文",作為面向連接的可靠協(xié)議,TCP實現(xiàn)必須 正確處理這種重復(fù)報文,因為二者可能最終都到達。 一個通常的TCP連接終止可以用圖描述如下: 代碼:client                     server             FIN M  close  ->  (被動關(guān)閉)  

44、0;          ACK M+1         <-             FIN N         <-  close             ACK N+1         ->  為什么需要 TIME_W

45、AIT 狀態(tài)? 假設(shè)最終的ACK丟失,server將重發(fā)FIN,client必須維護TCP狀態(tài)信息以便可以重發(fā) 最終的ACK,否則會發(fā)送RST,結(jié)果server認為發(fā)生錯誤。TCP實現(xiàn)必須可靠地終止連 接的兩個方向(全雙工關(guān)閉),client必須進入 TIME_WAIT 狀態(tài),因為client可能面 臨重發(fā)最終ACK的情形。 代碼:  scz 2001-08-31 13:28  先調(diào)用close()的一方會進入TIME_WAIT狀態(tài)    此外,考慮一種情況,TCP實現(xiàn)可能面臨先后兩個同樣的相關(guān)五元組。如果前一個連 接處在 TIME_WAIT 狀態(tài),而允

46、許另一個擁有相同相關(guān)五元組的連接出現(xiàn),可能處理 TCP報文時,兩個連接互相干擾。使用 SO_REUSEADDR 選項就需要考慮這種情況。 為什么 TIME_WAIT 狀態(tài)需要保持 2MSL 這么長的時間? 如果 TIME_WAIT 狀態(tài)保持時間不足夠長(比如小于2MSL),第一個連接就正常終止了。 第二個擁有相同相關(guān)五元組的連接出現(xiàn),而第一個連接的重復(fù)報文到達,干擾了第二 個連接。TCP實現(xiàn)必須防止某個連接的重復(fù)報文在連接終止后出現(xiàn),所以讓TIME_WAIT 狀態(tài)保持時間足夠長(2MSL),連接相應(yīng)方向上的TCP報文要么完全響應(yīng)完畢,要么被 丟棄。建立第二個連接的時候,不會混淆。 A: 小四

47、<scz> 在Solaris 7下有內(nèi)核參數(shù)對應(yīng) TIME_WAIT 狀態(tài)保持時間 # ndd -get /dev/tcp tcp_time_wait_interval 240000 # ndd -set /dev/tcp tcp_time_wait_interval 1000 缺省設(shè)置是240000ms,也就是4分鐘。如果用ndd修改這個值,最小只能設(shè)置到1000ms, 也就是1秒。顯然內(nèi)核做了限制,需要Kernel Hacking。 # echo "tcp_param_arr/W 0t0" | adb -kw /dev/ksyms /dev/mem phys

48、mem 3b72 tcp_param_arr: 0x3e8 = 0x0 # ndd -set /dev/tcp tcp_time_wait_interval 0 我不知道這樣做有什么災(zāi)難性后果,參看<<Unix編程/應(yīng)用問答中文版>>的聲明。 5.5TIME_WAIT 狀態(tài)保持時間為0會有什么災(zāi)難性后果?在普遍的現(xiàn)實應(yīng)用中,好象也 就是服務(wù)器不穩(wěn)定點,不見得有什么災(zāi)難性后果吧? D: rain Linux 內(nèi)核源碼 /usr/src/linux/include/net/tcp.h 中 #define TCP_TIMEWAIT_LEN (60*HZ) /* how lon

49、g to wait to successfully * close the socket, about 60 seconds */ 最好不要改為0,改成1。端口分配是從上一次分配的端口號+1開始分配的,所以一般 不會有什么問題。端口分配算法在tcp_ipv4.c中tcp_v4_get_port中。 5.6結(jié)構(gòu)在優(yōu)化編譯中的對齊問題 Q: 我正在寫一個流模塊,其中用到了#pragma pack(),當使用 gcc -D_KERNEL -c abc.c ld -r -o abc abc.o 編譯鏈接時,一切正常。為了獲得64-bit模塊,我必須使用Sun Workshop 5.0, 結(jié)果導(dǎo)致系統(tǒng)崩

50、潰。訪問 上面說必須在編譯鏈接應(yīng)用程序的時候指定"-misalign",所以我用了如下命令編譯 /opt/SUNWspro/bin/cc -D_KERNEL -misalign -c abc.c /usr/ccs/bin/ld -r -o abc abc.o 但是我不知道該如何在鏈接時指定"-misalign"。使用的是"/usr/ccs/bin/ld"。 A: Casper H.S. Dik - Network Security Engineer <Casper.DikHolland.Sun.Com> "-mi

51、salign"僅僅用于應(yīng)用程序,無法應(yīng)用到內(nèi)核編程中。"-misalign"使得編譯 獲得的代碼增加了一些runtime glue,它們將指示內(nèi)核模擬unaligned load(慢)。 作為內(nèi)核編程,沒有等效技術(shù)。 Q: 使用#pragma pack()是因為需要讀取來自Windows客戶端的報文,對端使用 #pragma pack(1)壓縮了所使用的數(shù)據(jù)結(jié)構(gòu) 代碼:   #pragma pack(1)     typedef struct pkt_hdr_struct     &#

52、160;        uint8_t  pkt_ver;         uint32_t pkt_type;         uint32_t pkt_len;      pkt_hdr_t;     #pragma pack()  為了采用這個結(jié)構(gòu)讀取網(wǎng)絡(luò)數(shù)據(jù),Solaris端的服務(wù)程序需要強制轉(zhuǎn)換匹配該結(jié)構(gòu), 但是一旦企圖讀取緊接在pkt_ver成員之后的pkt_typ

53、e成員,崩潰了。嘗試過其他 辦法,首先用一個字符指針讀取第一個字節(jié),然后指針增一,把該指針強制類型 轉(zhuǎn)換成( uint32_t * ),然后讀取數(shù)據(jù),依然崩潰。 此外,是否意味著無法在內(nèi)核模塊編程中使用#pragma pack() A: Ed L Cashin <> 我想你可以單獨寫一個pkt_header_read()函數(shù),單字節(jié)讀取然后拼裝成相應(yīng)的數(shù) 據(jù)類型。如果你想避免函數(shù)調(diào)用,可以使用"inline"關(guān)鍵字。 A: Casper H.S. Dik - Network Security Engineer <Casp

54、er.DikHolland.Sun.Com> 你是否意識到pkt_hdr_t結(jié)構(gòu)使得你必須自己轉(zhuǎn)換字節(jié)序(對端是x86平臺) 我不認為#pragma pack()是最好的解決辦法,考慮定義如下結(jié)構(gòu) 代碼:  struct phs              char ver;         char type4;         char len4;      

55、 采用memcpy()讀取數(shù)據(jù) memcpy( &phs.type0, &pkt.pkt_type, 4 ); A: Andrew Gabriel <andrewcucumber.demon.co.uk> 采用字符指針是正確的,但是你犯了個錯誤,編寫如下函數(shù) 代碼:int read_misaligned_int ( int * iptr )              int    i;         int 

56、;   value;         char * ptr  = ( char * )iptr;         char * vptr = ( char * )&         for ( i = 0; i < sizeof( int ); i+ )                      

57、;*vptr+ = *ptr+;                  return( value );       此外,既然你提到對端是x86平臺,可能還需要考慮字節(jié)序轉(zhuǎn)換的問題 A: W. Richard Stevens <1999年逝世,享年49歲> 代碼:/*  * return value:  *     1 big-endian  *     2

58、 little-endian  *     3 unknow  *     4 sizeof( short ) != 2  */  static int byte_order ( void )        union                short s;          char  c sizeof( s

59、hort ) ;      un;      un.s = 0x0201;      if ( 2 = sizeof( short ) )                if ( ( 2 = un.c0 ) && ( 1 = un.c1 ) )                        p

60、uts( "big-endian" );              return( 1 );                    else if ( ( 1 = un.c0 ) && ( 2 = un.c1 ) )                        puts(

61、 "little-endian" );              return( 2 );                    else                        puts( "unknow" );      

62、0;       return( 3 );                      else                puts( "sizeof( short ) = %d", sizeof( short ) );          return( 4 );      &

63、#160;     return( 3 );    /* end of byte_order */  D: CERNET 華中地區(qū)網(wǎng)絡(luò)中心 程序設(shè)計版 集體討論匯總 為了解決Unix自定義結(jié)構(gòu)在GCC優(yōu)化編譯中對齊問題,一般解決辦法是用如下宏封裝 自定義結(jié)構(gòu) 代碼:#pragma pack(1) struct my_arphdr ; #pragma pack() 如果是SPARC/Solaris,還可以這樣 代碼:struct my_arphdr _attribute_ (packed); 兩種辦法其實都可以用在Unix系統(tǒng)/GCC編譯器中。

64、D: mbufsmth 關(guān)于結(jié)構(gòu)中字節(jié)對齊問題,相應(yīng)編譯器選項為 GCC/G+ : -fpack-struct Sun Workshop cc/CC: -misalign 最好不這樣做,會大大降低程序效率,特別在某些架構(gòu)中。應(yīng)該嘗試用位操作來處理。 D: Unknownsmth GCC可以這么解決 代碼:#ifdef _GCC_ #define PACKED _attribute_(_packed_) #else #define PACKED #endif struct msg    u_int16_t PACKED first;    . ; 還是 V

65、C 簡單,#include <pshpack1.h> 就搞定了 A: gfh_nuaa DEC : #pragma pack(1) SUN : #pragma pack(1) AIX : 編譯時 -q align=packed HP-UX : #pragma pack 1 D: Joe Durusau 在 Visual C+ 中,使用 "-ZP1" 就可以讓編譯器對自定義結(jié)構(gòu)進行單字節(jié)對齊,實 際就是取消了對齊優(yōu)化。 A: 2001-12-20 13:09 1) 結(jié)構(gòu)內(nèi)部成員的pack 代碼:struct foo        char a;      int  b _attribute_ (packed);  ;  2) 整個結(jié)構(gòu)的pack 代碼:struct

溫馨提示

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

評論

0/150

提交評論