天天看點

socket程式設計的常見問題

  • 英文小冊原文位址:​​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。。。。哈哈哈哈,開個玩笑。

繼續閱讀