| 導購 | 订阅 | 在线投稿
分享
 
 
 

Windows Socket1.1 程序設計

來源:互聯網  2008-06-01 02:02:38  評論

[文章導讀]Windows Sockets 是從 Berkeley Sockets 擴展而來的,其在繼續 Berkeley Sockets 的基礎上,又進行了新的擴充

一、簡介

Windows Sockets 是從 Berkeley Sockets 擴展而來的,其在繼續 Berkeley Sockets 的基礎上,又進行了新的擴充。這些擴充主要是提供了一些異步函數,並增加了符合WINDOWS消息驅動特性的網絡事件異步選擇機制。

Windows Sockets由兩部分組成:開發組件和運行組件。

開發組件:Windows Sockets 實現文檔、應用程序接口(API)引入庫和一些頭文件。

運行組件:Windows Sockets 應用程序接口的動態鏈接庫(WINSOCK.DLL)。

二、主要擴充說明

1、異步選擇機制:

Windows Sockets 的異步選擇函數提供了消息機制的網絡事件選擇,當使用它登記網絡事件發生時,應用程序相應窗口函數將收到一個消息,消息中指示了發生的網絡事件,以及與事件相關的一些信息。

Windows Sockets 提供了一個異步選擇函數 WSAAsyncSelect(),用它來注冊應用程序感愛好的網絡事件,當這些事件發生時,應用程序相應的窗口函數將收到一個消息。

函數結構如下:

int PASCAL FAR WSAAsyncSelect(SOCKET s,HWND hWnd,unsigned int wMsg,long lEvent);

參數說明:

hWnd:窗口句柄

wMsg:需要發送的消息

lEvent:事件(以下爲事件的內容)

值:

含義:

FD_READ

期望在套接字上收到數據(即讀預備好)時接到通知

FD_WRITE

期望在套接字上可發送數據(即寫預備好)時接到通知

FD_OOB

期望在套接字上有帶外數據到達時接到通知

FD_ACCEPT

期望在套接字上有外來連接時接到通知

FD_CONNECT

期望在套接字連接建立完成時接到通知

FD_CLOSE

期望在套接字關閉時接到通知

例如:我們要在套接字讀預備好或寫預備好時接到通知,語句如下:

rc=WSAAsyncSelect(s,hWnd,wMsg,FD_READFD_WRITE);

假如我們需要注銷對套接字網絡事件的消息發送,只要將 lEvent 設置爲0

2、異步請求函數

在 Berkeley Sockets 中請求服務是阻塞的,WINDOWS SICKETS 除了支持這一類函數外,還增加了相應的異步請求函數(WSAAsyncGetXByY();)。

3、阻塞處理方法

Windows Sockets 爲了實現當一個應用程序的套接字調用處于阻塞時,能夠放棄CPU讓其它應用程序運行,它在調用處于阻塞時便進入一個叫「HOOK」的例程,此例程負責接收和分配WINDOWS消息,使得其它應用程序仍然能夠接收到自己的消息並取得控制權。

WINDOWS 是非搶先的多任務環境,即若一個程序不主動放棄其控制權,別的程序就不能執行。因此在設計Windows Sockets 程序時,盡管系統支持阻塞操作,但還是反對程序員使用該操作。但由于 SUN 公司下的 Berkeley Sockets 的套接字默認操作是阻塞的,WINDOWS 作爲移植的 SOCKETS 也不可避免對這個操作支持。

在Windows Sockets 實現中,對于不能立即完成的阻塞操作做如下處理:DLL初始化→循環操作。在循環中,它發送任何 WINDOWS 消息,並檢查這個 Windows Sockets 調用是否完成,在必要時,它可以放棄CPU讓其它應用程序執行(當然使用超線程的CPU就不會有這個麻煩了^_^)。我們可以調用 WSACancelBlockingCall() 函數取消此阻塞操作。

在 Windows Sockets 中,有一個默認的阻塞處理例程 BlockingHook() 簡單地獲取並發送 WINDOWS 消息。假如要對複雜程序進行處理,Windows Sockets 中還有 WSASetBlockingHook() 提供用戶安裝自己的阻塞處理例程能力;與該函數相對應的則是 SWAUnhookBlockingHook(),它用于刪除先前安裝的任何阻塞處理例程,並重新安裝默認的處理例程。請注重,設計自己的阻塞處理例程時,除了函數 WSACancelBlockingHook() 之外,它不能使用其它的 Windows Sockets API 函數。在處理例程中調用 WSACancelBlockingHook()函數將取消處于阻塞的操作,它將結束阻塞循環。

4、出錯處理

Windows Sockets 爲了和以後多線程環境(WINDOWS/UNIX)兼容,它提供了兩個出錯處理函數來獲取和設置當前線程的最近錯誤號。(WSAGetLastEror()和WSASetLastError())

5、啓動與終止

使用函數 WSAStartup() 和 WSACleanup() 啓動和終止套接字。

Windows Socket1.1 程序設計
更多內容請看Windows操作系統安全集 Windows操作系統安裝 Windows頻道專題,或 三、Windows Sockets網絡程序設計核心

我們終于可以開始真正的 Windows Sockets 網絡程序設計了。不過我們還是先看一看每個 Windows Sockets 網絡程序都要涉及的內容。讓我們一步步慢慢走。

1、啓動與終止

在所有 Windows Sockets 函數中,只有啓動函數 WSAStartup() 和終止函數 WSACleanup() 是必須使用的。

啓動函數必須是第一個使用的函數,而且它答應指定 Windows Sockets API 的版本,並獲得 SOCKETS的特定的一些技術細節。本結構如下:

int PASCAL FAR WSAStartup(Word wVersionRequested, LPWSADATA lpWSAData);

其中 wVersionRequested 保證 SOCKETS 可正常運行的 DLL 版本,假如不支持,則返回錯誤信息。

我們看一下下面這段代碼,看一下如何進行 WSAStartup() 的調用

WORD wVersionRequested;// 定義版本信息變量

WSADATA wsaData;//定義數據信息變量

int err;//定義錯誤號變量

wVersionRequested = MAKEWORD(1,1);//給版本信息賦值

err = WSAStartup(wVersionRequested, &wsaData);//給錯誤信息賦值

if(err!=0)

{

return;//告訴用戶找不到合適的版本

}

//確認 Windows Sockets DLL 支持 1.1 版本

//DLL 版本可以高于 1.1

//系統返回的版本號始終是最低要求的 1.1,即應用程序與DLL 中可支持的最低版本號

if(LOBYTE(wsaData.wVersion)!= 1 HIBYTE(wsaData.wVersion)!=1)

{

WSACleanup();//告訴用戶找不到合適的版本

return;

}

//Windows Sockets DLL 被進程接受,可以進入下一步操作

關閉函數使用時,任何打開並已連接的 SOCK_STREAM 套接字被複位,但那些已由 closesocket() 函數關閉的但仍有未發送數據的套接字不受影響,未發送的數據仍將被發送。程序運行時可能會多次調用 WSAStartuo() 函數,但必須保證每次調用時的 wVersionRequested 的值是相同的。

2、異步請求服務

Windows Sockets 除支持 Berkeley Sockets 中同步請求,還增加了了一類異步請求服務函數 WSAAsyncGerXByY()。該函數是阻塞請求函數的異步版本。應用程序調用它時,由 Windows Sockets DLL 初始化這一操作並返回調用者,此函數返回一個異步句柄,用來標識這個操作。當結果存儲在調用者提供的緩沖區,並且發送一個消息到應用程序相應窗口。常用結構如下:

HANDLE taskHnd;

char hostname="rs6000";

taskHnd = WSAAsyncBetHostByName(hWnd,wMsg,hostname,buf,buflen);

需要注重的是,由于 Windows 的內存對像可以設置爲可移動和可丟棄,因此在操作內存對象是,必須保證 WIindows Sockets DLL 對象是可用的。

3、異步數據傳輸

使用 send() 或 sendto() 函數來發送數據,使用 recv() 或recvfrom() 來接收數據。Windows Sockets 不鼓勵用戶使用阻塞方式傳輸數據,因爲那樣可能會阻塞整個 Windows 環境。下面我們看一個異步數據傳輸實例:

假設套接字 s 在連接建立後,已經使用了函數 WSAAsyncSelect() 在其上注冊了網絡事件 FD_READ 和 FD_WRITE,並且 wMsg 值爲 UM_SOCK,那麽我們可以在 Windows 消息循環中增加如下的分支語句:case UM_SOCK:

switch(lParam)

{

case FD_READ:

len = recv(wParam,lpBuffer,length,0);

break;

case FD_WRITE:

while(send(wParam,lpBuffer,len,0)!=SOCKET_ERROR)

break;

}

break;

4、出錯處理

Windows 提供了一個函數來獲取最近的錯誤碼 WSAGetLastError(),推薦的編寫方式如下:

len = send (s,lpBuffer,len,0);

of((len==SOCKET_ERROR)&&(WSAGetLastError()==WSAWOULDBLOCK)){...}

Windows Socket1.1 程序設計
更多內容請看Windows操作系統安全集

Windows操作系統安裝 Windows頻道專題,或

[文章導讀]Windows Sockets 是從 Berkeley Sockets 擴展而來的,其在繼續 Berkeley Sockets 的基礎上,又進行了新的擴充 一、簡介 Windows Sockets 是從 Berkeley Sockets 擴展而來的,其在繼續 Berkeley Sockets 的基礎上,又進行了新的擴充。這些擴充主要是提供了一些異步函數,並增加了符合WINDOWS消息驅動特性的網絡事件異步選擇機制。 Windows Sockets由兩部分組成:開發組件和運行組件。 開發組件:Windows Sockets 實現文檔、應用程序接口(API)引入庫和一些頭文件。 運行組件:Windows Sockets 應用程序接口的動態鏈接庫(WINSOCK.DLL)。 二、主要擴充說明 1、異步選擇機制: Windows Sockets 的異步選擇函數提供了消息機制的網絡事件選擇,當使用它登記網絡事件發生時,應用程序相應窗口函數將收到一個消息,消息中指示了發生的網絡事件,以及與事件相關的一些信息。 Windows Sockets 提供了一個異步選擇函數 WSAAsyncSelect(),用它來注冊應用程序感愛好的網絡事件,當這些事件發生時,應用程序相應的窗口函數將收到一個消息。 函數結構如下: int PASCAL FAR WSAAsyncSelect(SOCKET s,HWND hWnd,unsigned int wMsg,long lEvent); 參數說明: hWnd:窗口句柄 wMsg:需要發送的消息 lEvent:事件(以下爲事件的內容) 值: 含義: FD_READ 期望在套接字上收到數據(即讀預備好)時接到通知 FD_WRITE 期望在套接字上可發送數據(即寫預備好)時接到通知 FD_OOB 期望在套接字上有帶外數據到達時接到通知 FD_ACCEPT 期望在套接字上有外來連接時接到通知 FD_CONNECT 期望在套接字連接建立完成時接到通知 FD_CLOSE 期望在套接字關閉時接到通知 例如:我們要在套接字讀預備好或寫預備好時接到通知,語句如下: rc=WSAAsyncSelect(s,hWnd,wMsg,FD_READFD_WRITE); 假如我們需要注銷對套接字網絡事件的消息發送,只要將 lEvent 設置爲0 2、異步請求函數 在 Berkeley Sockets 中請求服務是阻塞的,WINDOWS SICKETS 除了支持這一類函數外,還增加了相應的異步請求函數(WSAAsyncGetXByY();)。 3、阻塞處理方法 Windows Sockets 爲了實現當一個應用程序的套接字調用處于阻塞時,能夠放棄CPU讓其它應用程序運行,它在調用處于阻塞時便進入一個叫「HOOK」的例程,此例程負責接收和分配WINDOWS消息,使得其它應用程序仍然能夠接收到自己的消息並取得控制權。 WINDOWS 是非搶先的多任務環境,即若一個程序不主動放棄其控制權,別的程序就不能執行。因此在設計Windows Sockets 程序時,盡管系統支持阻塞操作,但還是反對程序員使用該操作。但由于 SUN 公司下的 Berkeley Sockets 的套接字默認操作是阻塞的,WINDOWS 作爲移植的 SOCKETS 也不可避免對這個操作支持。 在Windows Sockets 實現中,對于不能立即完成的阻塞操作做如下處理:DLL初始化→循環操作。在循環中,它發送任何 WINDOWS 消息,並檢查這個 Windows Sockets 調用是否完成,在必要時,它可以放棄CPU讓其它應用程序執行(當然使用超線程的CPU就不會有這個麻煩了^_^)。我們可以調用 WSACancelBlockingCall() 函數取消此阻塞操作。 在 Windows Sockets 中,有一個默認的阻塞處理例程 BlockingHook() 簡單地獲取並發送 WINDOWS 消息。假如要對複雜程序進行處理,Windows Sockets 中還有 WSASetBlockingHook() 提供用戶安裝自己的阻塞處理例程能力;與該函數相對應的則是 SWAUnhookBlockingHook(),它用于刪除先前安裝的任何阻塞處理例程,並重新安裝默認的處理例程。請注重,設計自己的阻塞處理例程時,除了函數 WSACancelBlockingHook() 之外,它不能使用其它的 Windows Sockets API 函數。在處理例程中調用 WSACancelBlockingHook()函數將取消處于阻塞的操作,它將結束阻塞循環。 4、出錯處理 Windows Sockets 爲了和以後多線程環境(WINDOWS/UNIX)兼容,它提供了兩個出錯處理函數來獲取和設置當前線程的最近錯誤號。(WSAGetLastEror()和WSASetLastError()) 5、啓動與終止 使用函數 WSAStartup() 和 WSACleanup() 啓動和終止套接字。 [url=/bbs/detail_1785229.html][img]http://image.wangchao.net.cn/it/1323424223378.gif[/img][/url] 更多內容請看Windows操作系統安全集 Windows操作系統安裝 Windows頻道專題,或 三、Windows Sockets網絡程序設計核心   我們終于可以開始真正的 Windows Sockets 網絡程序設計了。不過我們還是先看一看每個 Windows Sockets 網絡程序都要涉及的內容。讓我們一步步慢慢走。   1、啓動與終止    在所有 Windows Sockets 函數中,只有啓動函數 WSAStartup() 和終止函數 WSACleanup() 是必須使用的。    啓動函數必須是第一個使用的函數,而且它答應指定 Windows Sockets API 的版本,並獲得 SOCKETS的特定的一些技術細節。本結構如下: int PASCAL FAR WSAStartup(Word wVersionRequested, LPWSADATA lpWSAData);   其中 wVersionRequested 保證 SOCKETS 可正常運行的 DLL 版本,假如不支持,則返回錯誤信息。 我們看一下下面這段代碼,看一下如何進行 WSAStartup() 的調用 WORD wVersionRequested;// 定義版本信息變量 WSADATA wsaData;//定義數據信息變量 int err;//定義錯誤號變量 wVersionRequested = MAKEWORD(1,1);//給版本信息賦值 err = WSAStartup(wVersionRequested, &wsaData);//給錯誤信息賦值 if(err!=0) { return;//告訴用戶找不到合適的版本 } //確認 Windows Sockets DLL 支持 1.1 版本 //DLL 版本可以高于 1.1 //系統返回的版本號始終是最低要求的 1.1,即應用程序與DLL 中可支持的最低版本號 if(LOBYTE(wsaData.wVersion)!= 1 HIBYTE(wsaData.wVersion)!=1) { WSACleanup();//告訴用戶找不到合適的版本 return; } //Windows Sockets DLL 被進程接受,可以進入下一步操作   關閉函數使用時,任何打開並已連接的 SOCK_STREAM 套接字被複位,但那些已由 closesocket() 函數關閉的但仍有未發送數據的套接字不受影響,未發送的數據仍將被發送。程序運行時可能會多次調用 WSAStartuo() 函數,但必須保證每次調用時的 wVersionRequested 的值是相同的。   2、異步請求服務    Windows Sockets 除支持 Berkeley Sockets 中同步請求,還增加了了一類異步請求服務函數 WSAAsyncGerXByY()。該函數是阻塞請求函數的異步版本。應用程序調用它時,由 Windows Sockets DLL 初始化這一操作並返回調用者,此函數返回一個異步句柄,用來標識這個操作。當結果存儲在調用者提供的緩沖區,並且發送一個消息到應用程序相應窗口。常用結構如下: HANDLE taskHnd; char hostname="rs6000"; taskHnd = WSAAsyncBetHostByName(hWnd,wMsg,hostname,buf,buflen);   需要注重的是,由于 Windows 的內存對像可以設置爲可移動和可丟棄,因此在操作內存對象是,必須保證 WIindows Sockets DLL 對象是可用的。    3、異步數據傳輸    使用 send() 或 sendto() 函數來發送數據,使用 recv() 或recvfrom() 來接收數據。Windows Sockets 不鼓勵用戶使用阻塞方式傳輸數據,因爲那樣可能會阻塞整個 Windows 環境。下面我們看一個異步數據傳輸實例:    假設套接字 s 在連接建立後,已經使用了函數 WSAAsyncSelect() 在其上注冊了網絡事件 FD_READ 和 FD_WRITE,並且 wMsg 值爲 UM_SOCK,那麽我們可以在 Windows 消息循環中增加如下的分支語句:case UM_SOCK: switch(lParam) { case FD_READ: len = recv(wParam,lpBuffer,length,0); break; case FD_WRITE: while(send(wParam,lpBuffer,len,0)!=SOCKET_ERROR) break; } break;   4、出錯處理    Windows 提供了一個函數來獲取最近的錯誤碼 WSAGetLastError(),推薦的編寫方式如下: len = send (s,lpBuffer,len,0); of((len==SOCKET_ERROR)&&(WSAGetLastError()==WSAWOULDBLOCK)){...} [url=/bbs/detail_1785229.html][img]http://image.wangchao.net.cn/it/1323424223475.gif[/img][/url] 更多內容請看Windows操作系統安全集 Windows操作系統安裝 Windows頻道專題,或
󰈣󰈤
王朝萬家燈火計劃
期待原創作者加盟
 
 
 
>>返回首頁<<
 
 
 
 
 熱帖排行
 
 
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有