- 英文小冊原文位址:beej.us/guide/bgnet…
- 作者:Beej
- 中文翻譯位址:www.chanmufeng.com/posts/netwo…
1. 我從哪擷取這些頭檔案資料?
如果你的系統中沒有自帶這些檔案,或許你根本就不需要他們。你得看一下你平台的使用手冊。
對了,如果你是為Windows開發程式,你隻需要
#include <winsock.h>
。
2. bind()報“Address already in use”異常怎麼辦?
你必須對正在監聽的socket使用
setsockopt()
函數,并設定
SO_REUSEADDR
選項。看一下
bind()
章節和
select()
章節中的例子,你就明白了。
3. 我該如何擷取到系統中已經打開的socket清單?
使用
netstat
指令。使用細節你需要參考man手冊,不過你隻要輸入下列指令就能擷取到一些不錯的資訊:
$ netstat
4. 我該如何檢視路由表(routing table)?
執行
route
指令(多數的Linux系統是在
/sbin
下),或者
netstat -r
指令。
5. 如果我隻有一台電腦,我該怎麼運作Client/Server程式?我需要連接配接外網嗎?
幸運的事,所有系統都有一個回環(loopback)虛拟網絡“裝置”,這個裝置位于核心中,并假裝自己是個網卡(這家夥就是
ifconfig
中列出的“
lo
”)。
假設你登陸一台名為“goat”的裝置,并在一個視窗中運作了Client程式,在另一個視窗中運作了Server端程式。或者你也可以在背景運作Server程式(用
server &
),在另一個視窗中運作Client程式。
loopback裝置
的用處就是,你可以使用
client goat
或者
client localhost
(因為“
localhost
”已經在你的
/etc/hosts
中定義好了),這樣你就可以讓client在沒有網絡的情況下也可以與server通信。
簡而言之,不需要改變任何代碼,就可以讓你的程式在沒有網絡的單機上運作!
6. 如果遠端斷開了連接配接,我該怎麼知道呢?
你可以分辨,因為
recv()
會傳回
0
。
7. 我自己怎麼實作“ping”這個小工具?啥是ICMP?我從哪兒能學到更多關于raw scoket和SOCK_RAW的知識?
你對
raw socket
的全部疑問都可以在 W. Richard Stevens’ UNIX Network Programming books這本書中找到答案。在Stevens’ UNIX Network Programming源代碼的
ping
子目錄中,你可以找到ping的源碼。
8. 我該如何改變或縮短調用connect()的過期時間?
這個問題 W. Richard Stevens 已經回答了,我們就不狗尾續貂了。你可以參考UNIX Network Programming源代碼中的 lib/connect_nonb.c。
其要點是,使用
socket()
建立一個socket descriptor,将其設定為
non-blocking
,調用
connect()
,如果一切順利,
connect()
将立即傳回
-1
,
errno
将設定為
EINPROGRESS
。然後,你可以調用
select()
,并在
read
和
write
集合中傳遞socket descriptor。如果沒有逾時,則表示
connect()
調用已完成。此時,你必須使用
getsockopt()
設定
SO_ERROR
選項,以擷取
connect()
調用的傳回值,如果沒有錯誤,該值應該為
0
。
最後,在你開始通過socket傳輸資料之前,你可能姜再将其設定為
blocking
。
這樣做有一個好處,就是讓你的程式在
connecting
(連接配接期間)也可以做别的事情。比如:你可以将
timeout
設定為500ms,并在每次
timeout
時更新螢幕上的提示資訊,然後再次調用
select()
。當你調用
select()
并逾時(例如,達到20次)時,你就知道是時候放棄這個連接配接了。
強烈建議你看看Stevens的源碼,找個好例子研究一下。
9. 我該怎麼寫Windows網絡程式?
首先,解除安裝Windows,然後裝一個Linux或者BSD。。。。哈哈哈哈,開個玩笑。