windows編程sockets及應(yīng)用03第二章使用_第1頁(yè)
windows編程sockets及應(yīng)用03第二章使用_第2頁(yè)
windows編程sockets及應(yīng)用03第二章使用_第3頁(yè)
windows編程sockets及應(yīng)用03第二章使用_第4頁(yè)
windows編程sockets及應(yīng)用03第二章使用_第5頁(yè)
已閱讀5頁(yè),還剩5頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、第二章 使用 Windows Sockets 1.1 編程在這一章,介紹如何使用Windows Sockets 1.1 編程,并了使用Windows Sockets1.1 編程的一些細(xì)節(jié)問(wèn)題。本章的均是基于Windows Sockets 1.1 規(guī)范的,在某些方面可能會(huì)和第六、七章對(duì)Windows Sockets 2 的不一致,請(qǐng)讀者注意這一區(qū)別。2.1 Windows Sockets 協(xié)議棧安裝檢查任何一個(gè)與Windows Sockets Import Library 聯(lián)接的應(yīng)用程序只需簡(jiǎn)單地調(diào)用WSAStartup()函數(shù)便可檢測(cè)系統(tǒng)中有沒(méi)有一個(gè)或多個(gè) Windows Sockets 實(shí)現(xiàn)

2、。而對(duì)于一個(gè)稍微聰明一些的應(yīng)用程序來(lái)說(shuō),它會(huì)檢查 PATH 環(huán)境變量來(lái)尋找有沒(méi)有 Windows Sockets 實(shí)現(xiàn)的實(shí)例(Windows Sockets.DLL)。對(duì)于每一個(gè)實(shí)例,應(yīng)用程序可以發(fā)出一個(gè) LoadLibrary()調(diào)用并且用WSAStartup()函數(shù)來(lái)得到這個(gè)實(shí)現(xiàn)的具體數(shù)據(jù)。這一版本的Windows Sockets 規(guī)范并沒(méi)有試圖明確地多個(gè)并發(fā)的Windows Sockets 實(shí)現(xiàn)共同工作的情況。但這個(gè)規(guī)范中沒(méi)有任何規(guī)定可以被解釋成是限制多個(gè) Windows Sockets DLL同時(shí)存在并且被一個(gè)或者多個(gè)應(yīng)用程序同時(shí)調(diào)用的。2.2 套接口2.2.1 基本概念通訊的基石是套

3、接口,一個(gè)套接口是通訊的一端。在這一端上你可以找到與其對(duì)應(yīng)的一個(gè)名字。一個(gè)正在被使用的套接口都有它的類型和與其相關(guān)的進(jìn)程。套接口存在于通訊域中。通訊域是為了處理一般的線程通過(guò)套接口通訊而引進(jìn)的一種抽象概念。套接口通常和同一個(gè)域中也可能穿越域的界限,但這時(shí)一定要執(zhí)行某種解釋程序)。Windows的套接換數(shù)據(jù)(Sockets 規(guī)范支持單一的通訊域,即ernet 域。各種進(jìn)程使用這個(gè)域互相之間用ernet 協(xié)議族來(lái)進(jìn)行通訊(Windows Sockets 1.1 以上的版本支持其他的域,例如Windows Sockets 2)。套接口可以根據(jù)通訊性質(zhì)分類;這種性質(zhì)對(duì)于用戶是可見的。應(yīng)用程序一般僅在同

4、一類的套接口間通訊。不過(guò)只要底層的通訊協(xié)議允許,不同類型的套接口間也照樣可以通訊。用戶目前可以使用兩種套接口,即流套接口和數(shù)據(jù)報(bào)套接口。流套接口提供了雙向的,有序的,無(wú)重復(fù)并且無(wú)邊界的數(shù)據(jù)流服務(wù)。數(shù)據(jù)報(bào)套接口支持雙向的數(shù)據(jù)流,但并不保證是可靠,有序,無(wú)重復(fù)的。也就是說(shuō),一個(gè)從數(shù)據(jù)報(bào)套接口接收信息的進(jìn)程有可能發(fā)現(xiàn)信息重復(fù)了,或者和發(fā)出時(shí)的順序不同。數(shù)據(jù)報(bào)套接口的一個(gè)重要特點(diǎn)是它保留了邊界。對(duì)于這一特點(diǎn),數(shù)據(jù)報(bào)套接口采用了與現(xiàn)在許多包交換網(wǎng)絡(luò)(例如以太網(wǎng))非常類似的模型。2.2.2 客戶機(jī)/服務(wù)器模型一個(gè)在建立分布式應(yīng)用時(shí)最常用的范例便是客戶機(jī)/服務(wù)器模型。在這種方案中客戶應(yīng)用程序向服務(wù)器程序請(qǐng)求

5、服務(wù)。這種方式隱含了在建立客戶機(jī)/服務(wù)器間通訊時(shí)的非對(duì)稱性??蛻魴C(jī)/服務(wù)器模型工作時(shí)要求有一套為客戶機(jī)和服務(wù)器所共識(shí)的慣例來(lái)保證服務(wù)能夠被提供(或被接受)。這一套慣例包含了一套協(xié)議。它必須在通訊的兩頭都被實(shí)現(xiàn)。根據(jù)不同的實(shí)際情況,協(xié)議可能是對(duì)稱的或是非對(duì)稱的。在對(duì)稱的協(xié)議中,每一方都有可能扮演主從角色;在非對(duì)稱協(xié)議中,一方被不可改變地認(rèn)為是主機(jī),而另一方則是從機(jī)。一個(gè)對(duì)稱協(xié)議的例子是ernet 中用于終端仿真的NET。而非對(duì)稱協(xié)議的例子是ernet 中的 FTP。無(wú)論具體的協(xié)議是對(duì)稱的或是非對(duì)稱的,當(dāng)服務(wù)被提供時(shí)必然存在“客戶進(jìn)程”和“服務(wù)進(jìn)程”。一個(gè)服務(wù)程序通常在一個(gè)眾所周知的地址對(duì)服務(wù)的請(qǐng)

6、求,也就是說(shuō),服務(wù)進(jìn)程一直處于休眠狀態(tài),直到一個(gè)客戶對(duì)這個(gè)服務(wù)的地址提出了連接請(qǐng)求。在這個(gè)時(shí)刻,服務(wù)程序被“驚醒”并且為客戶提供服務(wù)對(duì)客戶的請(qǐng)求作出適當(dāng)?shù)姆磻?yīng)。這一請(qǐng)求/相應(yīng)的過(guò)程可以簡(jiǎn)單的用圖 2-1 表示。雖然基于連接的服務(wù)是設(shè)計(jì)客戶機(jī)/服務(wù)器應(yīng)用程序時(shí)的標(biāo)準(zhǔn),但有些服務(wù)也是可以通過(guò)數(shù)據(jù)報(bào)套接口提供的。客戶機(jī)服務(wù)器進(jìn)程通訊設(shè)施請(qǐng)求請(qǐng)求響應(yīng)響應(yīng)圖 2-1 客戶機(jī)/服務(wù)器模型2.2.3 帶外數(shù)據(jù)注意:以下對(duì)于帶外數(shù)據(jù)(也稱為 TCP 緊急數(shù)據(jù))的,都是基于 BSD 模型而言的。用戶者必須注意,目前有兩種互相的關(guān)于RFC 793 的解釋,也就是在這基礎(chǔ)上,帶外數(shù)據(jù)這一概念才被引入的。而且 BSD

7、 對(duì)于帶外數(shù)據(jù)的實(shí)現(xiàn)并沒(méi)有符合RFC 1122 定下的主機(jī)的要求,為了避免互操作時(shí),應(yīng)用程序開發(fā)者最好不要使用帶外數(shù)據(jù),除非是與某一既成事實(shí)的服務(wù)互操作時(shí)所必須的。Windows Sockets 提供者也必須提供他們的產(chǎn)品對(duì)于帶外數(shù)據(jù)實(shí)現(xiàn)的語(yǔ)義的文擋(采用 BSD 方式或者是RFC 1122 方式)。規(guī)定一個(gè)特殊的帶外數(shù)據(jù)語(yǔ)義集已經(jīng)超出了Windows Sockets 規(guī)范的范圍。流套接口的抽象中包括了帶外數(shù)據(jù)這一概念,帶外數(shù)據(jù)是相連的每一對(duì)流套接口間一個(gè)邏輯上獨(dú)立的傳輸通道。帶外數(shù)據(jù)是獨(dú)立于普通數(shù)據(jù)傳送給用戶的,這一抽象要求帶外數(shù)據(jù)設(shè)備必須支持每一時(shí)刻至少一個(gè)帶外數(shù)據(jù)消息被可靠地傳送。這一消

8、息可能包含至少一個(gè)字節(jié);并且在任何時(shí)刻僅有一個(gè)帶外數(shù)據(jù)信息等候發(fā)送。對(duì)于僅支持帶內(nèi)數(shù)據(jù)的通訊協(xié)議來(lái)說(shuō)(例如緊急數(shù)據(jù)是與普通數(shù)據(jù)在同一序列中發(fā)送的),系統(tǒng)通常把緊急數(shù)據(jù)從普通數(shù)據(jù)中分離出來(lái)單獨(dú)存放。這就允許用戶可以在順序接收緊急數(shù)據(jù)和非順序接收緊急數(shù)據(jù)之間作出選擇(非順序接收時(shí)可以省去緩存數(shù)據(jù)的麻煩)。在這種情況下,用戶也可以“偷看一眼”緊急數(shù)據(jù)。某一個(gè)應(yīng)用程序也可能喜歡線內(nèi)處理緊急數(shù)據(jù),即把其作為普通數(shù)據(jù)流的一部分。這可以靠設(shè)置套接口選項(xiàng)中的 SO_OOBINLINE 來(lái)實(shí)現(xiàn)(參見 5.1.21 節(jié),setsockopt())。在這種情況下,應(yīng)用程序可能希望確定未讀數(shù)據(jù)中的哪一些是“緊急”的(

9、“緊急”這一術(shù)語(yǔ)通常應(yīng)用于線內(nèi)帶外數(shù)據(jù))。為了達(dá)到這個(gè)目的,在 Windows Sockets 的實(shí)現(xiàn)中就要在數(shù)據(jù)流保留一個(gè)邏輯記號(hào)來(lái)帶外數(shù)據(jù)從哪一點(diǎn)開始發(fā)送,一個(gè)應(yīng)用程序可以使用SIOCATMARK ioctlsocket()命令(參見 5.1.12 節(jié))來(lái)確定在記號(hào)之前是否還有未讀入的數(shù)據(jù)。應(yīng)用程序可以使用這一記號(hào)與其對(duì)方進(jìn)行重新同步。WSAAsyncSelect()函數(shù)可以用于處理對(duì)帶外數(shù)據(jù)到來(lái)。2.2.4 廣播數(shù)據(jù)報(bào)套接口可以用來(lái)向許多系統(tǒng)支持的網(wǎng)絡(luò)發(fā)送廣播數(shù)據(jù)包。要實(shí)現(xiàn)這種功能,網(wǎng)絡(luò)本身必須支持廣播功能,因?yàn)橄到y(tǒng)并不提供對(duì)廣播功能的任何模擬。廣播信息將會(huì)給網(wǎng)絡(luò)造成極重的負(fù)擔(dān),因?yàn)樗鼈?/p>

10、要求網(wǎng)絡(luò)上的每臺(tái)主機(jī)都為它們服務(wù),所以發(fā)送廣播數(shù)據(jù)包的能力被限制于那些用顯式標(biāo)記了允許廣播的套接口中。廣播通常是為了如下兩個(gè)原因而使用的:1. 一個(gè)應(yīng)用程序希望在本地網(wǎng)絡(luò)中找到一個(gè)資源,而應(yīng)用程序?qū)υ撡Y源的地址又沒(méi)有任何先驗(yàn)的知識(shí)。2. 一些重要的功能,例如路由要求把它們的給所有可以找到的鄰機(jī)。被廣播信息的目的地址取決于這一信息將在何種網(wǎng)絡(luò)上廣播。 ernet 域中支持一個(gè)速記地址用于廣播INADDR_BROADCAST。由于使用廣播以前必須有收到的廣播消息都帶有發(fā)送者的地址和端口。某些類型的網(wǎng)絡(luò)支持多種廣播的概念。例如 IEEE802.5 令牌環(huán)結(jié)構(gòu)便支持一個(gè)數(shù)據(jù)報(bào)套接口,所以所層廣播指示,

11、它用來(lái)控制廣播數(shù)據(jù)是否通過(guò)橋接器發(fā)送。Windows Sockets 規(guī)范沒(méi)有提供任何機(jī)制用來(lái)判斷某個(gè)應(yīng)用程序是基于何種網(wǎng)絡(luò)之上的,而且也沒(méi)有任何辦法來(lái)控制廣播的語(yǔ)義。2.3 字節(jié)順序el 處理器的字節(jié)順序是和 DEC VAX 處理器的字節(jié)順序一致的。因此它與 68000 型處理器以及ernet 的順序是不同的,所以用戶在使用時(shí)要特別以保證正確的順序。任何從Windows Sockets 函數(shù)對(duì) IP 地址和端的和傳送給Windows Sockets 函數(shù)的IP 地址和端均是按照網(wǎng)絡(luò)順序組織的,這也包括了 sockaddr_in 結(jié)構(gòu)這一數(shù)據(jù)類型中的 IP地址域和端口域(但不包括sin_fam

12、ily 域)??紤]到一個(gè)應(yīng)用程序通常用與“時(shí)間”服務(wù)對(duì)應(yīng)的端口來(lái)和服務(wù)器連接,而服務(wù)器提供某種機(jī)制來(lái)通知用戶使用另一端口。因此 getservbyname()函數(shù)返回的端已經(jīng)是網(wǎng)絡(luò)順序了,可以直接用來(lái)組成一個(gè)地址,而不需要進(jìn)行轉(zhuǎn)換。然而如果用戶輸入一個(gè)數(shù),而且指定使用這一端,應(yīng)用程序則必須在使用它建立地址以前,把它從主機(jī)順序轉(zhuǎn)換成網(wǎng)絡(luò)順序(使用 htons()(例如從 getpeername()函函數(shù))。相應(yīng)地,如果應(yīng)用程序希望顯示包含于某一地址中的端數(shù)中返回的),這一端就必須在被顯示前從網(wǎng)絡(luò)順序轉(zhuǎn)換到主機(jī)順序(使用 ntohs()函數(shù))。ernet 的字節(jié)順序是不同的,上述的轉(zhuǎn)換是無(wú)法避免的

13、,應(yīng)用程序的由于el 處理器和編寫者應(yīng)該使用作為Windows Sockets API 一部分的標(biāo)準(zhǔn)的轉(zhuǎn)換函數(shù),而不要使用自己的轉(zhuǎn)換函數(shù)代碼。因?yàn)閷?lái)的 Windows Sockets 實(shí)現(xiàn)有可能在主機(jī)字節(jié)順序與網(wǎng)絡(luò)字節(jié)順序相同的機(jī)器上運(yùn)行。因此只有使用標(biāo)準(zhǔn)的轉(zhuǎn)換函數(shù)的應(yīng)用程序是可移植的。2.4 套接口屬性選項(xiàng)Windows Sockets 規(guī)范支持的套接口屬性選項(xiàng)都列在對(duì) setsockopt()函數(shù)和 getsockopt()函數(shù)的敘述中。任何一個(gè) Windows Sockets 實(shí)現(xiàn)必須能夠識(shí)別所有這些屬性選項(xiàng),并且對(duì)每一個(gè)屬性選項(xiàng)都返回合理的數(shù)值。每一個(gè)屬性選項(xiàng)的缺省值列在下表中:選項(xiàng)

14、類型含義缺省值注意事項(xiàng)SO_ACCEPTCONBOOL套接口正在。FALSESO_BROADCASTBOOLFALSE套接口被設(shè)置為可以發(fā)送廣播數(shù)據(jù)。SO_DEBUGBOOL允許Debug。FALSE(*)S0_DONTLINGERBOOL如果為真,SO_LINGERTRUE選項(xiàng)被。SO_DONTROUTEBOOL路由被。FALSE(*)SO_ERROR0得到并且清除錯(cuò)誤狀態(tài)。SO_KEEPALIVEBOOLFALSE活躍信息正在被發(fā)送。SO_LINGERstruct返回目前的linger 信息。 l_onofflinger為 0FAR *SO_OOBINLINEBOOL帶外數(shù)據(jù)正在普通數(shù)據(jù)流

15、 FALSE中被接收。SO_RCVBUF決定于實(shí)現(xiàn) (*)接收緩沖區(qū)大小。SO_REUSEADDRBOOLFALSE該套接口的地址是否可被其他人使用。SO_SNDBUF決定于實(shí)現(xiàn) (*)發(fā)送緩沖區(qū)大小。SO_TYPE套接口類型(如SOCK_STREAM)。和套接口被創(chuàng)建時(shí)一致TCP_NAYBOOL采用Nagle進(jìn)行合并傳送。決定于實(shí)現(xiàn)(*) Windows Sockets 實(shí)現(xiàn)有可能在用戶調(diào)用setsockopt()函數(shù)時(shí)忽略這些屬性,并且在用戶調(diào)用getsockopt()函數(shù)時(shí)返回一個(gè)沒(méi)有變化的值。或者它可能在 setsockopt()時(shí)接受某個(gè)值,并且在getsockopt()時(shí)返回相應(yīng)的

16、數(shù)值,但事實(shí)上并沒(méi)有在任何地方使用它。2.5 數(shù)據(jù)庫(kù)文件getXbyY() 和 WSAAyncGetXByY() 這一類的例程是用來(lái)得到某種特殊的網(wǎng)絡(luò)信息的。getXbyY()例程最初(在第一版的 BERKELY UNIX 中)是被設(shè)計(jì)成一種在文本數(shù)據(jù)庫(kù)中查詢信息的機(jī)制。雖然Windows Sockets 實(shí)現(xiàn)可能用不同的方式來(lái)得到這些信息,但Windows Sockets應(yīng)用程序要求通過(guò)getXbyY()或 WSAAyncGetXByY()這一類例到的信息是一致。2.6 與 Berkeley 套接口的不同有一些很有限的地方,Windows Sockets API 必須與從嚴(yán)格地堅(jiān)持Berke

17、ley 傳統(tǒng)風(fēng)格中解放出來(lái)。通常這么做是因?yàn)樵赪indows 環(huán)境中實(shí)現(xiàn)的難度。2.6.1 套接口數(shù)據(jù)類型和錯(cuò)誤數(shù)值Windows Sockets 規(guī)范中定義了一個(gè)新的數(shù)據(jù)類型 SOCKET,這一類型的定義對(duì)于將來(lái)Windows Sockets 規(guī)范的升級(jí)是必要的。例如在Windows NT 中把套接口作為文件句柄來(lái)使用。這一類型的定義也保證了應(yīng)用程序向 Win/32 環(huán)境的可移植性。因?yàn)檫@一類型會(huì)自動(dòng)地從 16 位升級(jí)到 32 位。在 UNIX 中所有句柄包括套接口句柄,都是非負(fù)的短整數(shù),而且一些應(yīng)用程序把這一假設(shè)視為真理。Windows Sockets 句柄則沒(méi)有這一限制,除了 INVAL

18、ID_SOCKET 不是一個(gè)有效的套接口外,套接口可以取從 0 到 INVALID_SOCKET-1 之間的任意值。因?yàn)?SOCKET 類型是unsigned,所以編譯已經(jīng)存在于 UNIX 環(huán)境中的應(yīng)用程序的源代碼可能會(huì)導(dǎo)致signed/unsigned 數(shù)據(jù)類型不匹配的警告。這還意味著,在 socket()例程和 accept()例程返回時(shí),檢查是否有錯(cuò)誤發(fā)生就不應(yīng)該再使用把返回值和-1 比較的方法,或判斷返回值是否為負(fù)(這兩種方法在 BSD 中都是很普通,很合法的途徑)。取而代之的是,一個(gè)應(yīng)用程序應(yīng)該使用常量 INVALID_SOCKET,該常量已在 WINSOCK.H 中定義。例如:典型

19、的 BSD 風(fēng)格:s = socket(.);if (s = -1)./* of s0 */更優(yōu)良的風(fēng)格:s = socket(.);if (s = INVALID_SOCKET).2.6.2 select()函數(shù)和 FD_*宏由于一個(gè)套接口不再表示了 UNIX 風(fēng)格的小的非負(fù)的整數(shù),select()函數(shù)在 Windows SocketsAPI 中的實(shí)現(xiàn)有一些變化:每一組套接口仍然用fd_set 類型來(lái)代表,但是它并不是一個(gè)位掩碼。整個(gè)組的套接口是用了一個(gè)套接口的數(shù)組來(lái)實(shí)現(xiàn)的。為了避免潛在的,應(yīng)用程序應(yīng)該堅(jiān)持用 FD_宏來(lái)設(shè)置,初始化,清除和檢查fd_set 結(jié)構(gòu)。2.6.3 錯(cuò)誤代碼errn

20、o,h_errno,WSAGetLastError()Windows Sockets 實(shí)現(xiàn)所設(shè)置的錯(cuò)誤代碼是無(wú)法通過(guò)errno 變量得到的。另外對(duì)于 getXbyY()這一類的函數(shù),錯(cuò)誤代碼無(wú)法從 h_errno 變量得到。錯(cuò)誤代碼可以使用 WSAGetLastError()調(diào)用得到。這一函數(shù)在 5.3.11 中。這個(gè)函數(shù)在 Windows Sockets 實(shí)現(xiàn)中是作為 WIN/32 函數(shù)GetLastError()的先導(dǎo)函數(shù)(最終是一個(gè)別名)。這樣做是為了在多線程的進(jìn)程中為每一線到自己的錯(cuò)誤信息提供可靠的保障。為了保持與 BSD 的兼容性,應(yīng)用程序可以加入以下一行代碼:#define err

21、no WSAGetLastError()這就保證了用全程的errno 變量所寫的網(wǎng)絡(luò)程序代碼在單線程環(huán)境中可以正確使用。當(dāng)然,這樣做有許多明顯的缺點(diǎn):如果一個(gè)原程序包含了一段代碼對(duì)套接口和非套接口函數(shù)都用 errno變量來(lái)檢查錯(cuò)誤,那么這種機(jī)制將無(wú)法工作。此外,一個(gè)應(yīng)用程序不可能為 errno 賦一個(gè)新的值(在Windows Sockets 中,WSASetLastError()函數(shù)可以做到這一點(diǎn))。例如:典型的 BSD 風(fēng)格:r = recv(.);if (r = -1& errno = EWOULDBLOCK)./* 但請(qǐng)見下文 */更優(yōu)良的風(fēng)格:r = recv(.); if (r =

22、-1/* 但請(qǐng)見下文 */& WSAGetLastError() = EWOULDBLOCK).雖然為了兼容性原因,錯(cuò)誤常量與 4.3BSD 所提供的一致;應(yīng)用程序應(yīng)該盡可能地使用 “WSA”系列錯(cuò)誤代碼定義。例如,一個(gè)更準(zhǔn)確的上面程序片斷的版本應(yīng)該是:r = recv(.);if (r = -1/* 但請(qǐng)見下文 */& WSAGetLastError() = WSAEWOULDBLOCK).2.6.4 指針?biāo)袘?yīng)用程序與Windows Sockets 使用的指針都必須是 FAR 指針,為了方便應(yīng)用程序開發(fā)者使用,Windows Sockets 規(guī)范定義了數(shù)據(jù)類型 LPHOSTENT。2.6.

23、5 重命名的函數(shù)有兩種原因Berkeley 套接口中的函數(shù)必須重命名以避免與其他的 API: close()和 closesocket()在 Berkeley 套接口中,套接口出現(xiàn)的形式與標(biāo)準(zhǔn)文件描述字相同,所以 close()函數(shù)可以用來(lái)和關(guān)閉正規(guī)文件一樣來(lái)關(guān)閉套接口。雖然在 Windows Sockets API 中,沒(méi)有任何規(guī)定阻礙 Windows Sockets 實(shí)現(xiàn)用文件句柄來(lái)標(biāo)識(shí)套接口,但是也沒(méi)有任何規(guī)定要求這么做。套接口描述字并不認(rèn)為是和正常文件句柄對(duì)應(yīng)的,而且并不能認(rèn)為文件操作,例如 read(),write()和 close()在應(yīng)用于套接口后不能保證正確工作。套接口必須使用

24、 closesocket()例程來(lái)關(guān)閉,用 close()例程來(lái)關(guān)閉套接口是不正確的,這樣做的效果對(duì)于Windows Sockets 規(guī)范說(shuō)來(lái)也是未知的。 ioctl()和 iooctlsocket()許多 C 語(yǔ)言的運(yùn)行時(shí)系統(tǒng)出于與 Windows Sockets 無(wú)關(guān)的目的使用 ioctl()例程,所以Windows Sockets 定義ioctlsocket()例程。它被用于實(shí)現(xiàn) BSD 中用ioctl()和fcntl()實(shí)現(xiàn)的功能。2.6.6 阻塞例程和 EINPROGRESS 宏雖然Windows Sockets 支持關(guān)于套接口的阻塞操作,但是這種應(yīng)用是被的.如果程序員被迫使用阻塞模

25、式(例如一個(gè)準(zhǔn)備移植的已有的程序),那么他應(yīng)該清楚地知道 WindowsSockets 中阻塞操作的語(yǔ)義。有關(guān)細(xì)節(jié)請(qǐng)參見 .7 Windows Sockets 支持的最大套接口數(shù)目一個(gè)特定的 Windows Sockets 提供者所支持的套接口的最大數(shù)目是由實(shí)現(xiàn)確定的。任何一個(gè)應(yīng)用程序都不應(yīng)假設(shè)某個(gè)待定數(shù)目的套接口可用。這一點(diǎn)在 4.3.15 WSAStartup()中會(huì)被重申。而且一個(gè)應(yīng)用程序可以真正使用的套接口的數(shù)目和某一特定的實(shí)現(xiàn)所支持的數(shù)目是完全無(wú)關(guān)的。一個(gè) Windows Sockets 應(yīng)用程序可以使用的套接口的最大數(shù)目是在編譯時(shí)由常量FD_SETSIZE 決定的。

26、這個(gè)常量在 select()函數(shù)(參見 4.1.18)中被用來(lái)組建 fd_set 結(jié)構(gòu)。在WINSOCK.H 中缺省值是 64。如果一個(gè)應(yīng)用程序希望能夠使用超過(guò) 64 個(gè)套接口,則編程必須在每一個(gè)源文件包含 WINSOCK.H 前定義確切的 FD_SET 值。有就是在工程項(xiàng)目文件中的編譯器選項(xiàng)上加入這一定義。例如在使用法可以完成這項(xiàng)工作,C 時(shí)加入-DFD_SETSIZE=128 作為編譯命令的一個(gè)命令行參數(shù).要強(qiáng)調(diào)的是:FD_SET 定義的值對(duì) WindowsSockets 實(shí)現(xiàn)所支持的套接口的數(shù)目并無(wú)任何影響。2.6.8 頭文件為了方便基于Berkeley 套接口的已有的源代碼的移植,Wi

27、ndows Sockets 支持許多Berkeley 頭文件。這些Berkeley 頭文件被包含在 WINSOCK.H 中。所以一個(gè)Windows Sockets 應(yīng)用程序只需簡(jiǎn)單的包含 WINSOCK.H 就足夠了(這也是一種被使用的方法)。2.6.9 API 調(diào)用失敗時(shí)的返回值常量SOCKET_ERROR 是被用來(lái)檢查 API 調(diào)用失敗的。雖然對(duì)這一常量的使用并不是強(qiáng)制性的,但這是的。如下的例子表明了如何使用SOCKET_ERROR 常量典型的 BSD 風(fēng)格:r = recv(.); if (r = -1/* or r 0 */& errno = EWOULDBLOCK).更優(yōu)良的風(fēng)格:r = recv(.);if (r = SOCKET_ERROR& WSAGetLastError =

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論