程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> SOCKET類的設計和實現

SOCKET類的設計和實現

編輯:關於C語言

 

WinSock基本知識

這裡不打算系統地介紹socket或者WinSock的知識。首先介紹WinSock API函數,講解阻塞/非阻塞的概念;然後介紹socket的使用。

WinSock API

Socket接口是網絡編程(通常是TCP/IP協議,也可以是其他協議)的API。最早的Socket接口是Berkeley接口,在Unxi操作系統中實現。WinSock也是一個基於Socket模型的API,在Microsoft Windows操作系統類中使用。它在Berkeley接口函數的基礎之上,還增加了基於消息驅動機制的Windows擴展函數。Winscok1.1只支持TCP/IP網絡,WinSock2.0增加了對更多協議的支持。這裡,討論TCP/IP網絡上的API。

Socket接口包括三類函數:

第一類是WinSock API包含的Berkeley socket函數。這類函數分兩部分。第一部分是用於網絡I/O的函數,如

accept、Closesocket、connect、recv、recvfrom、Select、Send、Sendto

另一部分是不涉及網絡I/O、在本地端完成的函數,如

bind、getpeername、getsockname、getsocketopt、htonl、htons、inet_addr、inet_nton

ioctlsocket、listen、ntohl、ntohs、setsocketopt、shutdow、socket等

第二類是檢索有關域名、通信服務和協議等Internet信息的數據庫函數,如

gethostbyaddr、gethostbyname、gethostname、getprotolbyname

getprotolbynumber、getserverbyname、getservbyport。

第三類是Berkekley socket例程的Windows專用的擴展函數,如gethostbyname對應的WSAAsynGetHostByName(其他數據庫函數除了gethostname都有異步版本),select對應的WSAAsynSelect,判斷是否阻塞的函數WSAIsBlocking,得到上一次Windsock API錯誤信息的WSAGetLastError,等等。

從另外一個角度,這些函數又可以分為兩類,一是阻塞函數,一是非阻塞函數。所謂阻塞函數,是指其完成指定的任務之前不允許程序調用另一個函數,在Windows下還會阻塞本線程消息的發送。所謂非阻塞函數,是指操作啟動之後,如果可以立即得到結果就返回結果,否則返回表示結果需要等待的錯誤信息,不等待任務完成函數就返回。

首先,異步函數是非阻塞函數;

其次,獲取遠地信息的數據庫函數是阻塞函數(因此,WinSock提供了其異步版本);

在Berkeley socket函數部分中,不涉及網絡I/O、本地端工作的函數是非阻塞函數;

在Berkeley socket函數部分中,網絡I/O的函數是可阻塞函數,也就是它們可以阻塞執行,也可以不阻塞執行。這些函數都使用了一個socket,如果它們使用的socket是阻塞的,則這些函數是阻塞函數;如果它們使用的socket是非阻塞的,則這些函數是非阻塞函數。

創建一個socket時,可以指定它是否阻塞。在缺省情況下,Berkerley的Socket函數和WinSock都創建“阻塞”的socket。阻塞socket通過使用select函數或者WSAAsynSelect函數在指定操作下變成非阻塞的。WSAAsyncSelect函數原型如下。

int WSAAsyncSelect(

    SOCKET s,  

    HWND hWnd, 

    u_int wMsg,

    long lEvent    

   );

其中,參數1指定了要操作的socket句柄;參數2指定了一個窗口句柄;參數3指定了一個消息,參數4指定了網絡事件,可以是多個事件的組合,如:

FD_READ       准備讀

FD_WRITE      准備寫

FD_OOB        帶外數據到達

FD_ACCEPT     收到連接

FD_CONNECT   完成連接

FD_CLOSE      關閉socket。

用OR操作組合這些事件值,如FD_READ|FD_WRITE

WSAAsyncSelect函數表示對socket s監測lEvent指定的網絡事件,如果有事件發生,則給窗口hWnd發送消息wMsg。

假定應用程序的一個socket s指定了監測FD_READ事件,則在FD_READ事件上變成非阻塞的。當read函數被調用時,不管是否讀到數據都馬上返回,如果返回一個錯誤信息表示還在等待,則在等待的數據到達後,消息wMsg發送給窗口hWnd,應用程序處理該消息讀取網絡數據。

對於異步函數的調用,以類似的過程最終得到結果數據。以gethostbyname的異步版本的使用為例進行說明。該函數原型如下:

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved