本系統(WinKing)提供之 Windows Sockets API 介面乃是依照 1993年1月20日公布之 WINSOCK 第1.1版(如附錄)中所定義之函式 (routine); 包括了30個Berkeley Software Distribution (BSD) 的函式以及16個符合 Windows Message-driven 特性的函式。
BSD 函式包括:
accept() bind() closesocket() connect()
getpeername() getsockname() getsockopt() htonl()
htons() inet_addr() inet_ntoa() ioctlsocket()
listen() ntohl() ntohs() recv()
recvfrom() select() send() sendto()
setsockopt() shutdown() socket() gethostname()
gethostbyaddr() gethostbyname()
getprotobyname() getprotobynumber()
getservbyname() getservbyport()
Microsoft Windows-specific Extensions 函式包括:
WSAAsyncGetHostByAddr() WSAAsyncGetHostByName()
WSAAsyncGetProtoByName() WSAAsyncGetProtoByNumber()
WSAAsyncGetServByName() WSAAsyncGetServByPort()
WSAAsyncSelect() WSACancelAsyncRequest()
WSACancelBlockingCall() WSACleanup()
WSAGetLastError() WSAIsBlocking()
WSASetBlockingHook() WSASetLastError()
WSAStartup() WSAUnhookBlockingHook()
這些 API 介面適用於 Internet Protocol Suite (IPS,通常稱之為 TCP/IP),
支援 Stream (TCP) 及 Datagram (UDP) Socket。
Stream (TCP) Socket 提供「雙向」、「可靠」、「有次序」、「不重覆」之資料傳送。
Datagram (UDP) Socket 則提供「雙向」之溝通,但沒有「可靠」、「有次序」、「不重覆」等之保證; 所以使用者可能會收到無次序、重覆之資料,甚至資料在傳輸過程中也可能會遺漏。
[Blocking 與 Non-blocking 模式]
Blocking 模式:使用者呼叫此一模式之函式時,會進入此函式之內部,直到條件或資料完全符合時再回到呼叫點。
Non-blocking 模式:使用者呼叫此一模式之函式時,進入此函式之內部,依當時之條件或資料做適當之回覆,並不會停留在函式之內部到條件或資料完全符合後才回應。
使用者必需注意的是,WINSOCK 定義之 Blocking 模式與一般 Unix 的不太相同。WINSOCK定義允許應用程式在呼叫 Blocking 函式的同時,依舊能夠處理其它訊息 (Messages),包括Keyboard 及 Mouse 的事件;但是此時應用程式除了能用 WSACancelBlockingCall() 函式來取消原先之 locking 動作或用WSAIsBlocking() 函式來檢查目前是否有 Blocking 動作仍在進行外,不可以」在原先呼叫之Blocking 函式完成前再呼叫其它的 Socket 函式,不然後者會失敗且產生WSAINPROGRESS 的錯誤。
使用者呼叫 WSACancelBlockingCall()函式所取消的 Blocking 動作若不是accept() 或者 select()的話,那麽之後唯一可呼叫的 Socket 函式只有closesocket(),因為取消一個 Socket 的Blocking 動作會使其變成未定(Indeterminate) 狀態。
[Async (非同步) 模式]
使用者呼叫此一模式的函式時,並不會馬上得到要求的資料;而是當要求的動作完成後,系統再透過另一種方式來通知呼叫者。其好處是使用者不需等到答覆後才可以再做其它的動作或要求。
WINSOCK定義的 Async 模式是以「PostMessage」的方式告知使用者其要求已經完成;所以在呼叫此類函式時,必須告知 Windows Sockets DLL一些資訊,包括接受訊息的視窗 handle及訊息編號等。
[函式概說]
[BSD Socket 程式庫]
(1) accept():接受某一Socket的連接要求,以完成 Stream Socket 的連接。
格 式: SOCKET PASCAL FAR accept( SCOKET s,struct sockaddr FAR *addr,int FAR *addrlen );
參 數: s Socket的識別碼 addr 存放來連接的彼端的位址 addrlen addr的長度
傳回值: 成功 - 新的Socket識別碼 失敗 - INVALID_SOCKET (呼叫 WSAGetLastError() 可得知原因)
說明: Server 端之應用程式呼叫此一函式來接受 Client 端要求之Socket 連接動作;如果Server 端之 Socket 是為 Blocking 模式,且沒有人要求連接動作,那麽此一函式會Block 函式馬上回覆錯誤。accept() 函式的答覆值為一新的 Socket,此 Socket 不可再用來接受其它的連接要求;但是原先之 Socket 仍可接受其他人的連接要求。
(2) bind():指定 Socket 的 Local 位址 (Address)。
格 式: int PASCAL FAR bind( SOCKET s,const struct sockaddr FAR *name,int namelen );
參 數: s Socket的識別碼 name Socket的位址值,其格式為
struct sockaddr
{
u_short sa_family;
char sa_data[14];
};
namelen name的長度
傳回值: 成功 - 0
失敗 - SOCKET_ERROR (呼叫 WSAGetLastError() 可得知原因)
說明: 此一函式是指定 Local 位址及 Port 給某一未定名之 Socket。 使用者若不在意位址或 Port 的值,那麽他可以設定位址為 INADDR_ANY,及Port 為 0;那麽Windows Sockets 會自動將其設定適當之位址及 Port(1024 到 5000之間的值),使用者可以在此 Socket 真正連接完成後,呼叫 getsockname() 來獲知其被設定的值。
(3) closesocket():關閉某一Socket。
格 式: int PASCAL FAR closesocket( SOCKET s );
參 數: s Socket 的識別碼
傳回值: 成功 - 0
失敗 - SOCKET_ERROR (呼叫 WSAGetLastError() 可得知原因)
說明: 此一函式是用來關閉某一 Socket。
若是使用者原先對要關閉之 Socket 設定 SO_DONTLINGER,則在呼叫此一函式後,會馬上回覆,但是此一 Sokcet 尚未傳送完畢的資料會繼續送完後才關閉。
若是使用者原先設定此 Socket 為 SO_LINGER,則有兩種情況:
(a) Timeout 設為 0 的話,此一 Socket 馬上重新設定 (reset),未傳完或未收到的資料全部遺失。
(b) Timeout 不為 0 的話,則會將資料送完,或是等到 Timeout 發生後才關閉。
(4) connect():要求連接某一Socket到指定的對方。
格 式: int PASCAL FAR connect( SOCKET s,const struct sockaddr FAR *name,int namelen );
參 數: s Socket 的識別碼
name 此 Socket 想要連接的對方位址
namelen name的長度
傳回值:成功 - 0
失敗 - SOCKET_ERROR (呼叫WSAGetLastError()可得知原因)
說明: 此函式用來向對方要求建立連接。若是指定的對方位址為 0 的話,會傳回錯誤值。當連接建立完成後,使用者即可利用此一 Socket 來做傳送或接收資料之用了。
(5) getpeername():獲取已連接成功之 Socket 的對方位址。
格 式: int PASCAL FAR getpeername( SOCKET s,struct sockaddr FAR *name,int FAR *namelen );
參 數: s Socket 的識別碼
name 此 Socket 連接的對方位址
namelen name 的長度
傳回值: 成功 - 0
失敗 - SOCKET_ERROR (呼叫 WSAGetLastError() 可得知原因)
說明: 此函式可用來取得已連接成功的 Socket 的彼端之位址資料。
(6) getsockname():獲取 Socket 的 Local 位址資料。
格式: int PASCAL FAR getsockname( SOCKET s,struct sockaddr FAR *name,int FAR *namelen );
參數: s Socket 的識別碼
name 此 Socket 的 Local 位址
namelen name 的長度
傳回值: 成功 - 0
失敗 - SOCKET_ERROR (呼叫 WSAGetLastError() 可得知原因)
說明: 此函式是用來取得已設定位址或已連接之 Socket 的本端位址資料。若是此 Socket 被設定為 INADDR_ANY,則需等真正建立連接成功後才會傳回正確的位址。
(7) getsockopt():要求某一 Socket 目前狀態設定的資料。
格式: int PASCAL FAR getsockopt( SOCKET s,int level,int optname,char FAR *optval,int FAR *optlen );
參數: s= Socket的識別碼,level=選項設定的,level=optname 選項名稱,optval=選項的設定值,optlen=選項設定值的長度
傳回值: 成功 - 0
失敗 - SOCKET_ERROR (呼叫 WSAGetLastError() 可得知原因)
說明: 此函式用來獲取目前 Socket的某些狀態設定值。 WINSOCK 提供之 level 只有 SOL_SOCKET 及 IPPROTO_TCP optname則有以下 之選擇:(參見WINSOCK 第 29、30 頁之定義)
Value Type
-----------------------------------------------
SO_ACCEPTCONN BOOL
SO_BROADCAST BOOL
*SO_DEBUG BOOL
SO_DONTLINGER BOOL
*SO_DONTROUTE BOOL
*SO_ERROR int
*SO_KEEPALIVE BOOL
SO_LINGER struct linger FAR*
SO_OOBINLINE BOOL
*SO_RCVBUF int
SO_REUSEADDR BOOL
*SO_SNDBUF int
SO_TYPE int
TCP_NODELAY BOOL
(* 表示暫不提供此功能選項)
(8) htonl():將一 32 位元 u_long 的值由 host 的排列方式轉換成network 的排列方式。
格式: u_long PASCAL FAR htonl( u_long hostlong );
參數: hostlong 一個 32 位元 host 排列方式的數目
傳回值: 一個 32 位元 network 排列方式的數目
說明: 因為 network 的排列方式與 host 的排列方式可能不同,所以我們需要此一函式來做轉換。
(9) htons():將一 16 位元u_short 的值由 host 的排列方式轉換成network 的排列方式。
格 式: u_short PASCAL FAR htons( u_short hostshort );
參 數: hostshort 一個 16 位元 host 排列方式的數目
傳回值: 一個 16 位元 network 排列方式的數目
說明: 因為 network 的排列方式與 host 的排列方式可能不同,所以我們需要此一函式來做轉換。
(10) inet_addr():將字串格式的位址轉換成 32 位元 unsigned long 的格式。
格式: unsigned long PASCAL FAR inet_addr( const char FAR *cp );
參數: cp 一個代表位址的「點格式」(dotted) 字串
傳回值: 成功 - 一個代表 Internet 位址的 unsigned long
失敗 - INADDR_NONE
說明: 此函式將一「點格式」的位址字串轉換成適用之Intenet位址。
「點格式」字串可為以下四種方式之任一:
(i) a.b.c.d (ii) a.b.c (iii) a.b (iv) a