📘
Beej's Guide to Network Programming 正體中文版
  • 簡介
  • 原著資訊
  • 譯者誌謝
  • 進階資料
  • 簡體中文版
  • 中文授權
  • 聯絡譯者
  • 1. 導讀
    • 1.1. 本書的讀者
    • 1.2. 平台與編譯器
    • 1.3. 官方網頁與書本
    • 1.4. Solaris/SunOS 程式設計師該注意的事
    • 1.5. Windows 程式設計師該注意的事
    • 1.6. 來信原則
    • 1.7. 鏡射站台(Mirroring)
    • 1.8. 譯者該注意的
    • 1.9. 版權與散佈
  • 2. 何謂 Socket
    • 2.1 兩種 Internet Sockets
    • 2.2 底層漫談與網路理論
  • 3. IP address、結構與資料轉換
    • 3.1. IPv4 與 IPv6
      • 3.1.1. Sub network (子網段)
      • 3.1.2. Port Number(連接埠號碼)
    • 3.2. Byte Order(位元組順序)
    • 3.3. 資料結構
    • 3.4. IP 位址,續集
      • 3.4.1 Private Network
  • 4. 從 IPv4 移植為 IPv6
  • 5. System call 或 Bust
    • 5.1. getaddrinfo()-準備開始!
    • 5.2. socket()-取得 File Descriptor!
    • 5.3. bind()- 我在哪個 port?
    • 5.4. connect(),嘿!你好。
    • 5.5. listen()-有人會呼叫我嗎?
    • 5.6. accept()- 謝謝你 call 3490 port
    • 5.7. send() 與 recv()- 寶貝,我們來聊天!
    • 5.8. sendto() 與 recvfrom()- 來點 DGRAM
    • 5.9. close() 與 shutdown()- 你消失吧!
    • 5.10. getpeername()-你是誰?
    • 5.11. gethostname()-我是誰?
  • 6. Client-Server 基礎
    • 6.1. 簡單的 Stream Server
    • 6.2. 簡單的 Stream Client
    • 6.3. Datagram Sockets
  • 7. 進階技術
    • 7.1. Blocking(阻塞)
    • 7.2. select():同步 I/O 多工
    • 7.3. 不完整傳送的後續處理
    • 7.4. Serialization:如何封裝資料
    • 7.5. 資料封裝
    • 7.6. 廣播封包:Hello World!
  • 8. 常見的問題
  • 9. Man 使用手冊
    • 9.1. accept()
    • 9.2. bind()
    • 9.3. connect()
    • 9.4. close()
    • 9.5. getaddrinfo(), freeaddrinfo(), gai_strerror()
    • 9.6. gethostname()
    • 9.7. gethostbyname(), gethostbyaddr()
    • 9.8. getnameinfo()
    • 9.9. getpeername()
    • 9.10. errno
    • 9.11. fcntl()
    • 9.12. htons(), htonl(), ntohs(), ntohl()
    • 9.13. inet_ntoa(), inet_aton(), inet_addr
    • 9.14. inet_ntop(), inet_pton()
    • 9.15. listen()
    • 9.16. perror(), strerror()
    • 9.17. poll()
    • 9.18. recv(), recvfrom()
    • 9.19. select()
    • 9.20. setsockopt(), getsockopt()
    • 9.21. send(), sendto()
    • 9.22. shutdown()
    • 9.23. socket()
    • 9.24. struct sockaddr and pals
  • 10. 參考資料
    • 10.1. 書籍
    • 10.2. 網站參考資料
    • 10.3. RFC
  • 11. 原著誌謝
Powered by GitBook
On this page
Edit on GitHub
  1. 1. 導讀

1.5. Windows 程式設計師該注意的事

本文以前只討論一點 Windows,純粹是我很不喜歡。不過我應該要客觀的說 Windows 其實提供很多基本安裝,所以顯然是個完備的作業系統。

人家說:小別勝新婚,這裡我相信這句話是對的[或許是年紀的關係]。不過我只能說,我已經十幾年沒有用 Microsoft 的作業系統來做自己的工作了,這樣我很開心!

其實我可以打出安全牌,只告訴你:"沒問題阿,你儘量去用 Windows 吧!"… 沒錯,其實我是咬著牙根說這些話的。

所以我還是在拉攏你來試試 Linux [1]、BSD [2],或一些 Unix 風格的系統。

不過人們各有所好,而 Windows 的使用者也樂於知道這份文件的內容能用在 Windows,只是需要改變一點程式碼而已。

你可以安裝一個酷玩意兒- Cygwin [3],這是讓 Windows 平台使用的 Unix 工具集。我曾在秘密情報網聽過,這個能讓全部的程式不經過修改就能編譯。

不過有些人可能想要用純 Windows 的方法來做。只能說你很有勇氣,而你所要做的事就是:立刻去弄個 Unix!喔,不是,我開玩笑的。這些日子以來,大家一直認為我對 Windows 是很友善的。

你所要做的事情就是[除非你安裝了 Cygwin!]:首先要忽略我這邊提過的很多系統 header(標頭檔),而你唯一需要 include (引用)的是:

#include <winsock.h>

等等,在你用 socket 函式庫做任何事情之前,必須要先呼叫 WSAStartup()。程式碼看起來像這樣:

#include <winsock.h>
{
  WSADATA wsaData; // if this doesn't work
  //WSAData wsaData; // then try this instead

  // MAKEWORD(1,1) for Winsock 1.1, MAKEWORD(2,0) for Winsock 2.0:

  if (WSAStartup(MAKEWORD(1,1), &wsaData) != 0) {
    fprintf(stderr, "WSAStartup failed.\n");
    exit(1);
  }

你也必須告訴編譯器要連結 Winsock 函式庫,在 Winsock 2.0 通常稱為 wsock32.lib 或 winsock32.lib 或 ws2_32.lib。在 VC++ 底下,可以透過專案(Project)選單,在設定(Settings)底下 …。按下 Link 標籤,並找到 "Object/library modules" 的標題。新增 "wsock32.lib"(或者你想要用的函式庫)到清單中。

最後,當你處理好 socket 函式庫時,你需要呼叫 WSACleanup(),細節請參考線上手冊。

只要你做好這些工作,本文後面的範例應該都能順利編譯,只有少部分例外。

還有一件事情,你不能用 close() 關閉 socket,你要用 closesocket() 來取代。而且 select() 只能用在 socket descriptors 上,不能用在 file descriptors(像 stdin 的值就是 0)。

還有一種你能用的 socket 類型,CSocket,細節請查詢你的編譯器使用手冊。

要取得更多關於 Winsock 的訊息可以先閱讀 Winsock FAQ [4]。

最後,我聽說 Windows 沒有 fork() system call,我在一些範例中會用到。你可能需要連結到 POSIX 函式庫或要讓程式能動的一些函式庫,或許你也可以用 CreateProcess() 來取代。fork() 不需要參數,但是 CreateProcess() 卻需要大約 480 億個參數。如果你不想用,CreateThread() 會稍微比較容易理解 … 不過多執行緒(multithreading)的討論則不在本文件的範疇中。我只能盡量提及,你要體諒!

Previous1.4. Solaris/SunOS 程式設計師該注意的事Next1.6. 來信原則

Last updated 2 years ago

[1]

[2]

[3]

[4]

http://www.linux.com/
http://www.bsd.org/
http://www.cygwin.com/
http://tangentsoft.net/wskfaq/