1 Winsock簡(jiǎn)介
1.1 Winsock頭文件及庫(kù)文件
-
Winsock有兩個(gè)版本:Winsock1和Winsock2溅潜,都能在WinCE之外的Windows系統(tǒng)運(yùn)行。
WinCE只支持Winsock1抑诸。
1.2 Winsock初始化
int WSAStartup(
WORD wVersionRequested,
LPWSADATA lpWSAData
);
- 函數(shù)解釋
- 參數(shù)
- wVersionRequested:指定準(zhǔn)備加載的Winsock庫(kù)的版本烂琴,其中高位字節(jié)表示次版本,低位字節(jié)表示主版本蜕乡〖楸粒可以使用MAKEWORD(x,y)獲得,x:高异希,y:低健盒。
- lpWSAData:一般以需要設(shè)置前面兩個(gè)成員即可。
- 參數(shù)
1.3 錯(cuò)誤檢查和處理
int WSAGetLastError(void);
int WSASetLastError(void); // ?
1.3 協(xié)議尋址
- 協(xié)議
- IP:是一種無(wú)連接協(xié)議称簿,不能確保數(shù)據(jù)傳輸?shù)某晒Γ?/li>
- TCP和UDP使用IP進(jìn)行面向連接和無(wú)連接的數(shù)據(jù)通信扣癣。所以稱作TCP/IP和UDP/TP。
- IPv4尋址
- 通過(guò)
SOCKADDR_IN
結(jié)構(gòu)來(lái)指定IP地址和服務(wù)端口信息憨降。- sin_family字段必須設(shè)置為AF_INET父虑,已告知Winsock此時(shí)正在使用IP地址族。
- sin_port定義端口授药。
- sin_addr保存IP地址士嚎。
-
inet_addr
函數(shù):把點(diǎn)分IP地址轉(zhuǎn)換成32位無(wú)符號(hào)長(zhǎng)整數(shù)。 - 字節(jié)排序
-
big-endian
:字節(jié)的排序從最無(wú)意義的字節(jié)到最有意義的字節(jié)悔叽; -
little-endian
:字節(jié)的排序從最有意義的字節(jié)到最無(wú)意義的字節(jié)莱衩; - 主機(jī)字節(jié)(host-byte):主機(jī)實(shí)際字節(jié)順序。
- 網(wǎng)絡(luò)字節(jié)順序:即big_endian娇澎。
- 常用函數(shù)
- 主機(jī)字節(jié)序轉(zhuǎn)網(wǎng)絡(luò)字節(jié)序
u_long htonl(u_long hostlong);
int WSAHtonl(SOCKET s, u_long hostlong, u_long FAR* lpnetlong);
u_short htons(u_short hostshort);
WSAHtons(SOCKET s, u_short hostshort, u_short FAR* lpnetshort);
- 網(wǎng)絡(luò)字節(jié)序轉(zhuǎn)主機(jī)字節(jié)序
u_long ntonl(u_long netlong);
int WSANtohl(SOCKET s, u_long netlong, u_long FAR* lphostlong);
u_short ntohs(u_short netshort);
int WSANtohs(SOCKET s, u_short netshort, ushort FAR* lphostshort);
- 主機(jī)字節(jié)序轉(zhuǎn)網(wǎng)絡(luò)字節(jié)序
-
- 通過(guò)
1.5 創(chuàng)建套接字
-
SOCKET
SOCKET socket{ int af;// 協(xié)議地址族笨蚁,IP為AF_INET int type;// 協(xié)議的套接字類型,TCP:SOCK_STREAM趟庄,UDP:SOCK_DGRAM int protocol;// TCP:IPPROTO_TCP括细,UDP:IPROTO_UDP };
Winsock兩種基本通信技術(shù):面向連接的通信和無(wú)連接的通信。
1.6 面向連接的通信
1.6.1 服務(wù)器API函數(shù)
1.6.1.1 綁定
一旦為某種協(xié)議創(chuàng)建了套接字戚啥,就必須將套接字綁定到一個(gè)已知的地址上奋单。
-
bind函數(shù)
int bind( SOCKET s, // 等待客戶連接的服務(wù)器套接字 const struct sockaddr FAR* name, // 地址緩沖區(qū) int namelen );
-
bind常見錯(cuò)誤
- WSAEADDRINUSE:如果是TCP/IP,那么說(shuō)明另一個(gè)進(jìn)程已經(jīng)同本地IP接口及端口號(hào)綁定了猫十,或者那個(gè)IP接口和端口號(hào)處于TIME_OUT狀態(tài)览濒。
- WSAEFAULT:說(shuō)明該套接字已被綁定呆盖。
1.6.1.2 監(jiān)聽
-
listen函數(shù)
int listen( SOCKET s,// 一個(gè)已經(jīng)被綁定的套接字 int backlog // 指定了被擱置的連接的對(duì)大隊(duì)列長(zhǎng)度 );
backlog:
- 假定該參數(shù)為2,那么當(dāng)有3個(gè)客戶機(jī)同時(shí)發(fā)出請(qǐng)求匾七,那么前面兩個(gè)會(huì)被放在一個(gè)“掛起”隊(duì)列中絮短,而第三個(gè)連接請(qǐng)求會(huì)失敗。并返回WSAECONNREFUSED錯(cuò)誤碼昨忆。
- 當(dāng)服務(wù)器接受了一個(gè)連接丁频,那么該連接就會(huì)從隊(duì)列中刪除,以便別人可以繼續(xù)發(fā)出請(qǐng)求邑贴。
- 其本身也有限制席里,該限制是由下層的協(xié)議提供程序決定的。如果這個(gè)參數(shù)出現(xiàn)非法值拢驾,那么系統(tǒng)會(huì)用與之最接近的一個(gè)合法值來(lái)取代奖磁。但是如何找出實(shí)際的backlog值,還不存在一種標(biāo)準(zhǔn)的方案繁疤。
1.6.1.3 接受連接
-
accept函數(shù)
SOCKET accept( SOCKET s, // 一個(gè)已經(jīng)被綁定的套接字 struct socketaddr FAR* addr, int FAR* addrlen );
-
函數(shù)說(shuō)明
- accept函數(shù)返回后咖为,addr結(jié)構(gòu)中會(huì)包含發(fā)出連接請(qǐng)求的那個(gè)客戶機(jī)的IPv4地址信息,而addrlen參數(shù)則指出addr結(jié)構(gòu)的長(zhǎng)度稠腊。
- accept函數(shù)會(huì)返回一個(gè)新的套接字描述符躁染,對(duì)應(yīng)已經(jīng)被接受的那個(gè)客戶機(jī)連接。
1.6.2 客戶端API函數(shù)
客戶端創(chuàng)建步驟:
- 創(chuàng)建套接字架忌;
- 建立一個(gè)SOCKADDR地址結(jié)構(gòu)吞彤,結(jié)構(gòu)名稱為準(zhǔn)備連接的服務(wù)器名。
- 用connect或WSAConnect初始化客戶機(jī)與服務(wù)器的連接叹放。
-
TCP狀態(tài)
- 套接字狀態(tài):CLSOED饰恕、ESTABLISHED、SYN_SENT井仰、SYN_RCVD等埋嵌。
- 套接字主動(dòng)關(guān)閉以及被動(dòng)關(guān)閉。
-
connect函數(shù)
int connect( SOCKET s, const struct socketaddr FAR* name, int namelen );
常見錯(cuò)誤碼:
- WSAECONNREFUSED:想要連接的計(jì)算機(jī)沒有用于監(jiān)聽的進(jìn)程俱恶;
- WSAETIMEOUT:試圖連接的計(jì)算機(jī)不可用(也有可能是硬件故障莉恼,或主機(jī)沒有聯(lián)網(wǎng)等);
1.6.3 數(shù)據(jù)傳輸
常見錯(cuò)誤:
- WSAECONNRESET:連接正在被關(guān)閉速那,可能是超時(shí)、通信方關(guān)閉連接尿背。
- WSAEWOULDBLOCK:一般套接字處于非阻塞模式或異步狀態(tài)時(shí)會(huì)返回端仰。
1.6.3.1 send
和WSASend
-
send函數(shù)
int send( SOCKET s, const char FAR* buf, int len, int flags );
常見錯(cuò)誤
- WSAECONNABORTED:一般在虛擬回路由于超時(shí)或協(xié)議有錯(cuò)而中斷是發(fā)生。此時(shí)表明該套接字不能在使用田藐,應(yīng)將其關(guān)閉荔烧。
- WSAECONNRESET:遠(yuǎn)程主機(jī)上的應(yīng)用程序通過(guò)執(zhí)行強(qiáng)行關(guān)閉或意外中斷操作重新設(shè)置虛擬回路吱七,或遠(yuǎn)程主機(jī)重新啟動(dòng)。也需要關(guān)閉該套接字鹤竭。
- WSAETIMEOUT:網(wǎng)路故障或遠(yuǎn)程連接系統(tǒng)異常死機(jī)而導(dǎo)致連接中斷踊餐。
1.6.3.2recv
和WSARecv
-
send函數(shù)
int recv( SOCKET s, char FAR* buf, int len, int flags );
常見錯(cuò)誤
- WSAEMSGSIZE:當(dāng)掛起數(shù)據(jù)大于所提供的緩沖區(qū),緩沖區(qū)會(huì)盡量讓數(shù)據(jù)填滿臀稚。此時(shí)recv調(diào)用會(huì)產(chǎn)生該錯(cuò)誤吝岭,但該錯(cuò)誤只會(huì)在UDP協(xié)議出現(xiàn),TCP不會(huì)吧寺。
注意:慎用MSG_PEEK標(biāo)記窜管。
1.6.4 流協(xié)議
1.6.5 中斷連接
從容關(guān)閉連接的套路是先調(diào)用shutdown
函數(shù)后再調(diào)用closesocket
函數(shù)。
1.6.5.1 shutdown
函數(shù)
-
shutdown函數(shù)
int shutdown( SOCKET s, int how );
該函數(shù)對(duì)UDP而言毫無(wú)意義稚机,因?yàn)樗菬o(wú)連接的幕帆。
1.6.5.2 closesocket
函數(shù)
-
closesocket函數(shù)
int closesocket(SOCKET s);
1.7 無(wú)連接通信(UDP/IP)
UDP不能確保可靠的數(shù)據(jù)傳輸赖条,但能將數(shù)據(jù)發(fā)送到多個(gè)目標(biāo)失乾,或者接受的多個(gè)源數(shù)據(jù)。
數(shù)據(jù)的傳輸使用數(shù)據(jù)報(bào)纬乍,即離散信息包碱茁。
1.7.1 接收端
-
步驟
- 用socket或WSASocket創(chuàng)建套接字;
- 把套接字和準(zhǔn)備接收的數(shù)據(jù)綁定在一起(bind函數(shù))蕾额;
- 調(diào)用接收函數(shù)早芭。
-
接收函數(shù)
-
rcvfrom
函數(shù)int recvform( SOCKET s, char FAR* buf, int len, int flags, struct sockaddr FAR* from, int FAR* fromlen );
注意:慎用MSG_PEEK標(biāo)記。
-
WSARecvFrom
函數(shù)略
-
1.7.2 發(fā)送端
-
步驟
- 建立套接字诅蝶;
- 調(diào)用發(fā)送函數(shù)(
sendto
或者WSASendTo
)退个。
-
發(fā)送函數(shù)
-
sendto
函數(shù)int sendto( SOCKET s, const char FAR* buf, int len, int flags, const struct sockaddr FAR* to, int tolen );
-
WSAendTo
函數(shù)略
-
1.7.3 基于消息的協(xié)議
面向連接的通信同時(shí)也是流協(xié)議,無(wú)連接通信幾乎都是基于消息的调炬。
-
收發(fā)數(shù)據(jù)考慮點(diǎn)
-
面向消息的協(xié)議保留了數(shù)據(jù)邊界语盈,所以提交給發(fā)送函數(shù)的數(shù)據(jù)在發(fā)送完之前會(huì)形成阻塞。對(duì)非阻塞I/O模式而言缰泡,如果數(shù)據(jù)未能完全發(fā)送刀荒,發(fā)送函數(shù)就會(huì)返回WSAEWOULDBLOCK錯(cuò)誤。需要再次調(diào)用發(fā)送函數(shù)棘钞。
記撞琛:對(duì)于基于消息的協(xié)議而言,寫入操作只能作為一種自動(dòng)行為發(fā)生宜猜。
連接的另一端泼返,對(duì)接收函數(shù)的調(diào)用必須提供一個(gè)足夠大的緩沖空間。否則會(huì)出現(xiàn)WSAEMSGSIZE錯(cuò)誤姨拥。此時(shí)緩沖區(qū)會(huì)被填滿绅喉,且未接收的數(shù)據(jù)會(huì)被丟棄渠鸽。且無(wú)法恢復(fù)。(唯一特例是支持部分消息的協(xié)議)
-
多個(gè)網(wǎng)絡(luò)接口機(jī)器上發(fā)送UDP/IP消息問(wèn)題柴罐。
UDP套接字不會(huì)真正和網(wǎng)絡(luò)接口綁定在一起徽缚,而是建立一種關(guān)聯(lián),即使用
bind
顯示綁定IP接口稱為發(fā)出去的UDP數(shù)據(jù)報(bào)的源IP地址革屠。但是真正決定數(shù)據(jù)報(bào)在哪個(gè)物理接口上發(fā)送出去的凿试,是路由表。意味著屠阻,如果先執(zhí)行顯式綁定红省,源IP地址就可能有誤,即源IP地址可能不是真正在它上面發(fā)送數(shù)據(jù)報(bào)的那個(gè)接口的IP地址国觉。
書上并沒有把問(wèn)題講清楚吧恃,需后續(xù)在查找資料。
-
1.7.4 釋放資源
本來(lái)就是無(wú)連接麻诀,對(duì)它不用太客氣痕寓,直接調(diào)用closesocket
函數(shù)即可。
1.8 其他API函數(shù)
1.8.1 getpeername
函數(shù)
用于獲取通信方的套接字地址信息蝇闭。
1.8.2 getsockname
函數(shù)
該函數(shù)對(duì)應(yīng)getpeername
函數(shù)呻率。返回給定套接字的本地接口地址信息。
1.8.3 WSADuplicateSocket
函數(shù)(套接字復(fù)制函數(shù))
用于建立WSAPROTOCOL_INFO結(jié)構(gòu)呻引,該結(jié)構(gòu)可以傳遞至另一個(gè)進(jìn)程礼仗。這樣另一個(gè)進(jìn)程打開指向同一個(gè)下層套接字的句柄,如此一來(lái)逻悠,這個(gè)進(jìn)程也能對(duì)該資源進(jìn)行操作元践。
該函數(shù)生成的套接字描述符被稱為共享套接字描述符。
注意點(diǎn):
- 需考慮進(jìn)程間通信問(wèn)題童谒;
- 需考慮I/O同步問(wèn)題单旁;
- 使用該函數(shù)復(fù)制出的描述符的進(jìn)程關(guān)閉該套接字,不會(huì)影響其他進(jìn)程饥伊。直到最后一個(gè)描述符調(diào)用關(guān)閉套接字之前象浑,下層套接字依然保持打開狀態(tài)。
- 利用任何一個(gè)共享描述符執(zhí)行
WSAAsyncSelect
函數(shù)或WSAEventSelect
函數(shù)時(shí)琅豆,都會(huì)刪除以前所有的套接字事件注冊(cè)愉豺。
1.9 Windows CE
2 設(shè)計(jì)Winsock
2.1 系統(tǒng)體系結(jié)構(gòu)
提供程序:具體執(zhí)行應(yīng)用程序的Winsock API調(diào)用的程序。具體調(diào)用哪個(gè)提供程序茫因,由WS2_32.dll確定粒氧。
-
提供程序分類
基礎(chǔ)提供程序:位于傳輸層頂端
-
分層提供程序:
位于WS2_32.dll之下,基礎(chǔ)提供程序之上;
-
能截獲并操縱Winsock調(diào)用外盯;
如果應(yīng)用程序利用分層提供程序創(chuàng)建了一個(gè)套接字,分層提供程序?qū)⑹褂迷撎捉幼纸孬@所有的Winsock調(diào)用翼雀。分層提供程序可能會(huì)阻塞饱苟、修改調(diào)用,也可能將未修改的調(diào)用傳遞給底層的提供程序狼渊。
2.2 協(xié)議的特征
2.2.1 面向消息
如果某種協(xié)議將字節(jié)當(dāng)做一條獨(dú)立的消息在網(wǎng)上傳輸箱熬,則稱該協(xié)議是面向消息的。如UDP狈邑。
保留消息邊界:發(fā)送端向接收端發(fā)送三個(gè)數(shù)據(jù)報(bào)城须,接收端在第一次接收時(shí),并不會(huì)把所有的三個(gè)數(shù)據(jù)報(bào)返回米苹,即使它已經(jīng)全部接收糕伐。
2.2.1 面向流
不保留消息邊界的協(xié)議通常被稱作“基于流的協(xié)議”。
流服務(wù)的定義是連續(xù)的數(shù)據(jù)傳輸蘸嘶;
- 對(duì)于接收端:不管消息邊界是否存在良瞧,接收端都會(huì)盡量的讀取有效數(shù)據(jù);只要數(shù)據(jù)一到達(dá)網(wǎng)絡(luò)堆棧训唱,網(wǎng)絡(luò)堆棧就開始讀取它,并將它放在緩沖區(qū)中等待進(jìn)程處理。
- 對(duì)于發(fā)送端:系統(tǒng)會(huì)將原始消息分解成小消息或者把幾條消息積累在一起利诺,并形成一個(gè)較大的數(shù)據(jù)包翁脆。
2.2.3 偽流
對(duì)于發(fā)送端:依然是發(fā)送離散消息;跟面向消息一樣澳骤。
對(duì)于接收端:將接收到的數(shù)據(jù)放在緩沖池中歧强,接收應(yīng)用程序可隨意讀取宴凉;類似面向流誊锭。
2.2.4 面向連接和無(wú)連接
通常,一個(gè)協(xié)議要么提供面向連接的服務(wù)弥锄,要么提供無(wú)連接的服務(wù)丧靡。
- 面向連接:進(jìn)行數(shù)據(jù)交換之前必須建立一條路徑。
- 無(wú)連接:不在乎接收端是否在偵聽籽暇,直接發(fā)温治。
2.2.5 可靠性和有序性
面向連接可靠性高,也可保證有序性戒悠。但是二者不可兼得熬荆。
2.2.6 正常關(guān)閉
只出現(xiàn)在面向連接的協(xié)議中。
2.2.7 廣播數(shù)據(jù)
即從一個(gè)工作站發(fā)出的數(shù)據(jù)绸狐,局域網(wǎng)內(nèi)的所有工作站都能收到卤恳。
2.2.8 多播數(shù)據(jù)
指一個(gè)進(jìn)程發(fā)送數(shù)據(jù)而一個(gè)或多個(gè)接收端可以接收到數(shù)據(jù)的能力累盗。
2.2.9 服務(wù)質(zhì)量
體現(xiàn)了應(yīng)用程序請(qǐng)求獨(dú)占網(wǎng)絡(luò)帶寬的能力。
2.2.10 部分消息
只用于面向消息的協(xié)議突琳。
2.2.11 路由選擇的考慮
路由器會(huì)直接丟棄非路由協(xié)議數(shù)據(jù)包若债,即使兩臺(tái)機(jī)器連接在同一路由器。
2.2.12 其他特征
2.3 Winsock編錄(Winsock目錄)
Winsock編錄是一個(gè)數(shù)據(jù)庫(kù)拆融,它包含系統(tǒng)中可用的各種不同的協(xié)議蠢琳。
-
WSAEnumProtocols
函數(shù):獲取系統(tǒng)中安裝的網(wǎng)絡(luò)協(xié)議的相關(guān)信息。
2.3.1 Winsock編錄和Win64
64位應(yīng)用程序使用64位Winsock編錄镜豹;
32位應(yīng)用程序使用32位Winsock編錄傲须。
2.3.2 創(chuàng)建套接字
- 多個(gè)提供程序可以共享一個(gè)地址族、套接字類型及協(xié)議趟脂。需使用
WSASocket
函數(shù)代替socket
函數(shù)泰讽。
3 網(wǎng)際協(xié)議
3.1 IPv4
3.1.1 尋址
-
IPv4地址分類
種類 網(wǎng)絡(luò)部分 第1個(gè)數(shù)字 端點(diǎn)數(shù)字 A 8位 0-127 16 777 216 B 16位 128-191 65 536 C 24位 193-223 256 D N/A 224-239 N/A E N/A 240-255 N/A 例:172.31.28.120/16
解析:地址的前16位表示地址的網(wǎng)絡(luò)部分,相當(dāng)于子網(wǎng)掩碼為255.255.0.0散怖。
127.0.0.1:環(huán)回地址菇绵,指向本地計(jì)算機(jī)。
3.1.1.1 單播
分配到單個(gè)計(jì)算機(jī)接口上的地址稱為單播地址镇眷,該地址僅可以分配到一個(gè)接口上咬最。A/B/C3類地址組成IPv4的單播地址空間。
3.1.1.2 多播
多播地址是D類地址欠动。
3.1.1.3 廣播
受限廣播地址:255.255.255.255永乌。
3.1.2 IPv4管理協(xié)議
IPv4需要依賴其他協(xié)議才能實(shí)現(xiàn)其功能。
-
ARP(Address Resolution Protocol):地址解析協(xié)議
將一個(gè)32位IPv4地址解析為一個(gè)物理地址或硬件地址具伍,使用IPv4數(shù)據(jù)包能夠被包裝在適當(dāng)?shù)拿襟w幀中翅雏。
- 如果目標(biāo)地址位于局域網(wǎng)內(nèi),則ARP請(qǐng)求將針對(duì)目的地的物理地址人芽。
- 如果一個(gè)或者多個(gè)路由器將源和目的地分離開來(lái)望几,則ARP請(qǐng)求將針對(duì)缺省網(wǎng)關(guān),數(shù)據(jù)包也將發(fā)往該網(wǎng)關(guān)萤厅。
-
ICMP(Internet Control Message Protocol):Internet控制信息協(xié)議
目的是為了在IPv4主機(jī)之間發(fā)送狀態(tài)信息和錯(cuò)誤信息橄抹。也被用來(lái)搜尋鄰近路由器。
-
IGMP(Internet惕味, Management Protocol):Internet組管理協(xié)議
用來(lái)管理多播組的成員楼誓。
3.1.3 Winsock中的IPv4尋址
- 端口號(hào)分類
- 0~1023:由IANA控制,為已知服務(wù)所保留名挥;
- 1024~49151:已注冊(cè)端口號(hào)疟羹,由普通用戶執(zhí)行的普通用戶進(jìn)程或程序可以使用這些端口;
- 49152~65535:動(dòng)態(tài)和(或)專用端口。
- 如果沒有顯示綁定端口號(hào)榄融,系統(tǒng)會(huì)把套接字隱式地綁定到1024~5000范圍內(nèi)的一個(gè)本地端口上参淫。
3.2 IPv6
-
NAT(Network Address Translators):網(wǎng)絡(luò)地址轉(zhuǎn)換器。
將多個(gè)專用地址映射到單個(gè)的公共IP地址上愧杯。
該節(jié)略黄刚。
3.3 地址及名稱解析
3.3.1 名稱解析例程
-
名稱解析函數(shù)
getnameinfo
函數(shù)和getaddrinfo
函數(shù):可以兼容IPv4和IPv6,用以代替gethostbyname
函數(shù)和inet_addr
函數(shù)民效。 使用:包含
WS2TCPIP.H
頭文件,并在其之前包含WSPIAPI.H
頭文件涛救。
該章略過(guò)畏邢,后面主要講述一些使用新函數(shù)的示例代碼。
4 Winsock支持的其他協(xié)議(略過(guò))
5 WinsockI/O方法
5.1 套接字模式
5.1.1 阻塞模式
I/O操作完成前检吆,執(zhí)行操作的Winsock調(diào)用會(huì)一直等待下去舒萎。
5.1.2 非阻塞模式
Winsock函數(shù)無(wú)論如何都會(huì)立即返回。
5.2 套接字I/O模型
5.2.1 阻塞模型
優(yōu)點(diǎn):簡(jiǎn)潔蹭沛;
缺點(diǎn):浪費(fèi)資源臂寝,難以擴(kuò)展到很多連接的情況。
5.2.2 select模型
工作原理是利用select
函數(shù)實(shí)現(xiàn)對(duì)I/O的管理摊灭。
優(yōu)點(diǎn):從單個(gè)線程的多套接字上進(jìn)行多重連接及I/O操作咆贬。避免阻塞模式的線程劇增。
缺點(diǎn):也是單線程的缺點(diǎn)一般最大不超過(guò)1024的套接字帚呼。
5.2.3 WSAAsyncSelect模型
消息通知:應(yīng)用程序可在一個(gè)套接字上接收以Windows消息為基礎(chǔ)的網(wǎng)絡(luò)事件掏缎。
-
WSAAsyncSelect
函數(shù)int WSAAsyncSelect( SOCKET s, // 發(fā)出網(wǎng)絡(luò)事件的套接字 HWND hWnd, // 接收網(wǎng)絡(luò)事件的窗口 unsigned int wMsg, // 發(fā)生網(wǎng)絡(luò)事件時(shí)接收的消息 long lEvent // 代表一個(gè)掩碼,指定一系列網(wǎng)絡(luò)事件的組合 );
注意:
- 多個(gè)事件必須在套接字上一次完成注冊(cè)煤杀;
- 除非明確調(diào)用
closesocket
函數(shù)眷蜈,或者調(diào)用WSAAsyncSelect
函數(shù)更改注冊(cè)的網(wǎng)絡(luò)事件,否則沈自,時(shí)間通知總是有效酌儒; - 將
lEvent
參數(shù)置為0,則效果相當(dāng)于停止在套接字上進(jìn)行的所有網(wǎng)絡(luò)事件枯途。
調(diào)用
WSAAsyncSelect
函數(shù)后忌怎,套接字的模式會(huì)從阻塞模式自動(dòng)變成非阻塞模式。-
FD_WRITE發(fā)出條件:
- 使用```connect``或者WSAConnect柔袁,一個(gè)套接字首次建立連接呆躲;
- 使用accept或者WSAAccept,套接字被接受以后捶索;
- 若send插掂、WSASend、sendto或WSASendTo操作失敗,返回了WSAEWOULDBLOCK錯(cuò)誤辅甥,而且緩沖區(qū)的空間變得可用酝润。
優(yōu)點(diǎn):在系統(tǒng)開銷不大的情況下同時(shí)處理許多連接。
缺點(diǎn):即使應(yīng)用程序不需要窗口璃弄,也必須創(chuàng)建一個(gè)窗口要销;且一個(gè)窗口處理成千上萬(wàn)的套接字中的所有事件,性能成為瓶頸夏块。
5.2.4 WSAEventSelect模型
事件通知:通過(guò)事件對(duì)象句柄完成網(wǎng)絡(luò)事件處理疏咐。
-
步驟
// 創(chuàng)建事件對(duì)象(人工重設(shè)事件對(duì)象) // 兩種工作狀態(tài):signaled/non-signaled // 兩種工作模式:manualreset/autoreset WSAEVENT WSACreEvent(void); // 注冊(cè)事件消息通知 int WSAEventSelect( SOCKET s, WSAEVENT hEventObject, long lNetWorkEvents ); // 修改事件工作狀態(tài) BOOL WSAResetEvent(void); // 關(guān)閉事件 BOOL WSACloseEvent(WSAEVENT hEvent); // 等待一個(gè)或多個(gè)網(wǎng)絡(luò)事件對(duì)象句柄 DWORD WSAWaitForMultiEvent( DWORD cEvents, const WSAEVENT FAR* lphEvent, BOOL fWaitAll, DWORD dwTimeout, BOOL fAlertable );
優(yōu)點(diǎn):概念簡(jiǎn)單;不需要窗口環(huán)境脐供。
缺點(diǎn):最多只支持64個(gè)事件浑塞。擴(kuò)充只能通過(guò)住址線程池解決。
5.2.5 重疊模型(該節(jié)略過(guò))
可通過(guò)ReadFile和WriteFile兩個(gè)函數(shù)實(shí)現(xiàn)在設(shè)備上執(zhí)行I/O操作政己。但是考慮到跨平臺(tái)性酌壕,建議使用WSARecv和WSASend函數(shù)。
- 步驟
- 創(chuàng)建套接字歇由;
- 將套接字與本地接口綁定卵牍;
- 可通過(guò)事件對(duì)象通知和完成例程來(lái)管理重疊I/O請(qǐng)求的完成情況。
5.2.5.1 事件通知
要求將Windows事件對(duì)象與WSAOVERLAPPED結(jié)構(gòu)關(guān)聯(lián)沦泌。
5.2.6 完成端口模型(該節(jié)略過(guò))
6 可伸縮的Winsock應(yīng)用程序(略過(guò))
6.1 API及可伸縮性
6.1.1 AcceptEx
6.1.2 GetAcceptExSockaddrs
6.1.3 TransitFile
6.1.4 TransmitPackets
6.1.5 ConnectEx
6.1.6 DisconnectEx
6.1.7 WSARecvMsg
6.2 可伸縮的服務(wù)器體系結(jié)構(gòu)
6.2.1 接受連接
6.2.2 數(shù)據(jù)傳輸
6.3 資源管理
6.4 服務(wù)器策略
6.4.1 高吞吐率
6.4.2 最大化連接數(shù)
6.4.3 性能指標(biāo)
6.5 Winsock直連及套接字直連協(xié)議
7 套接字選項(xiàng)和I/O控制指令
7.1 套接字選項(xiàng)
7.1.1 SOL_SOCKET選項(xiàng)級(jí)別
7.1.2 SOL_APPLETALK選項(xiàng)級(jí)別
7.1.3 SOL_IRLMP選項(xiàng)級(jí)別
7.1.4 IPPROTO_IP選項(xiàng)級(jí)別
7.1.5 IPPROTO_IPV6選項(xiàng)級(jí)別
7.1.6 IPPROTO_RM選項(xiàng)級(jí)別
7.1.7 IPPROTO_TCP選項(xiàng)級(jí)別
7.1.8 NSPROTO_IPX選項(xiàng)級(jí)別
7.2 IOCTLSOCKET糊昙、WSAIOCTL和WSANSPloctl
8 名稱注冊(cè)和解析
8.1 背景知識(shí)
名稱注冊(cè)是一個(gè)過(guò)程,它把一個(gè)用戶友好的名稱和具體協(xié)議地址關(guān)聯(lián)在一起赦肃。
8.2 命名空間模型
- 命名空間提供用一個(gè)友好名把具體的協(xié)議及其尋址屬性關(guān)聯(lián)在一起的功能溅蛉。如針對(duì)IP的DNS。
- 分類
- 動(dòng)態(tài)命名空間:允許實(shí)時(shí)注冊(cè)服務(wù)他宛;
- 靜態(tài)命名空間:須手動(dòng)注冊(cè)船侧,無(wú)法使用Winsock用它來(lái)注冊(cè)服務(wù)名;
- 固定命名空間:允許實(shí)時(shí)注冊(cè)服務(wù)厅各;和動(dòng)態(tài)命名空間不同的是它把注冊(cè)信息保留在固定地方镜撩。
- WSAEnumNameSpaceProvider:獲取系統(tǒng)上所有的命名空間。
8.3 服務(wù)的注冊(cè)
需要利用命名空間提供程序注冊(cè)服務(wù)队塘。
服務(wù)類**:描述哪些命名空間可用來(lái)注冊(cè)服務(wù)袁梗;
服務(wù):服務(wù)是啥?憔古?遮怜?TODO
8.3.1 安裝服務(wù)類
函數(shù):WSAInstallServiceClass
8.3.2 服務(wù)的注冊(cè)
函數(shù):WSASetService
8.3.3 服務(wù)注冊(cè)示例
8.4 服務(wù)的查詢
WSALookupServiceBegin
WSALookupServiceNext
WSALookupServiceEnd
8.4.1 怎樣查詢服務(wù)
8.4.2 查詢DNS
8.4.3 查詢NLA
9 多播
9.1 多播的含義
找到多播屬性
9.2 IP多播
9.3 可靠多播
9.4 ATM多播
10 常規(guī)服務(wù)質(zhì)量
10.1 背景知識(shí)
10.1.1 RSVP
10.1.2 網(wǎng)絡(luò)組件
10.1.3 應(yīng)用組件
10.1.4 策略組件
10.2 QOS和Winsock
10.3 終止QOS
10.4 QOS編程
10.5 示例
10.6 ATM和QOS
11 原始套接字
利用原始套接字可以訪問(wèn)位于基層的傳輸層協(xié)議。利用原始套接字來(lái)模擬IP的一些實(shí)用程序鸿市,如Traceroute和Ping等锯梁。
11.1 創(chuàng)建原始套接字
11.2 ICMP
便于不同主機(jī)之間傳遞消息的一種機(jī)制即碗。
11.2.1 Ping示例
11.2.2 Traceroute示例
11.3 使用IP頭包含選項(xiàng)
12 Winsock服務(wù)提供程序接口(SPI)
- 分類
-
傳輸服務(wù)提供程序
-
分層服務(wù)提供程序:
- 會(huì)將自己安裝在Winsock編目里,并位于基礎(chǔ)服務(wù)提供程序之上陌凳,可能位于其他分層提供程序之間剥懒。
- 截獲應(yīng)用程序?qū)insock API調(diào)用;
- 如果應(yīng)用程序創(chuàng)建的套接字和某個(gè)分層提供程序的特征匹配合敦,則該分層服務(wù)提供程序就會(huì)被調(diào)用初橘。
- 基礎(chǔ)服務(wù)提供程序:公開一個(gè)Winsock接口,直接執(zhí)行一種協(xié)議充岛。
-
分層服務(wù)提供程序:
-
命名空間提供程序
- 類似傳輸服務(wù)提供程序保檐,只是它截獲的是名稱解析的Winsock API調(diào)用,如gethostbyname或WSALookupServiceBegin崔梗;
- 將自己安裝在命名空間編錄中展东,當(dāng)應(yīng)用程序執(zhí)行的名稱解析搜索和它匹配時(shí),命名空間提供程序就會(huì)被調(diào)用炒俱。
- SPI函數(shù)前綴
- WSC:安裝、刪除或修改分層提供程序及命名空間提供程序爪膊;
- WSP:分層服務(wù)提供程序API权悟;
- WPU:分層服務(wù)提供程序使用的支持函數(shù);
- NSP:命名空間提供程序API推盛。
-
傳輸服務(wù)提供程序
12.1 分層服務(wù)提供程序(LSP)
12.1.1 安裝LSP
12.1.1.1 安裝提供程序條目
12.1.1.2 刪除LSP
12.1.1.3 修改LSP條目
12.1.2 編寫分層提供程序
12.1.2.1 初始化提供程序
12.1.2.2 創(chuàng)建套接字
12.1.2.3 處理I/O
- 阻塞與非阻塞
- Select和WSPSelect
- WSAAsyncSelect
- WSAEventSelect
- 重疊I/O
12.1.2.4 Winsock擴(kuò)展函數(shù)
12.1.2.5 各種要求
12.1.3 調(diào)試LSP
- 危害:開發(fā)的LSP出現(xiàn)一個(gè)錯(cuò)誤峦阁,就極有可能使所有訪問(wèn)Winsock位于LSP下邊的協(xié)議的應(yīng)用程序崩潰。如果發(fā)生在IP上耘成,則注入LSASS之類的關(guān)鍵性服務(wù)都會(huì)停止榔昔。
- 解決:必須重啟計(jì)算機(jī),進(jìn)入安全模式瘪菌,并卸載LSP撒会,就可以將Winsock編錄恢復(fù)回正常狀態(tài)。
- 比較好的做法是在重啟系統(tǒng)之前對(duì)LSP進(jìn)行調(diào)試师妙。
12.1.4 LSP示例
12.2 命名空間服務(wù)提供程序
12.2.1 命名空間的安裝
12.2.2 命名空間的實(shí)現(xiàn)
12.2.3 命名空間提供程序示例
13 使用C#進(jìn)行.NET套接字編程
14 Visual Basic Winsock控件
15 遠(yuǎn)程訪問(wèn)服務(wù)
15.1 RAS客戶機(jī)
15.2 編譯和鏈接
15.3 數(shù)據(jù)結(jié)構(gòu)和平臺(tái)兼容性問(wèn)題
15.4 DUN1.3升級(jí)和Windows95
15.5 RASDIAL
15.6 電話簿
15.7 連接管理
15.8 VPN
16 IP助手函數(shù)
以編程方式獲取如下IP實(shí)用程序中的可用功能:
- ipconfig.exe
- ipv6.exe
- netstat.exe
- route.exe
- arp.exe