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]。

[1] http://www.linux.com/

[2] http://www.bsd.org/

[3] http://www.cygwin.com/

[4] http://tangentsoft.net/wskfaq/

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

Last updated