1 Winsock簡介
1.1 Winsock頭文件及庫文件
-
Winsock有兩個版本: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庫的版本,其中高位字節(jié)表示次版本,低位字節(jié)表示主版本。可以使用MAKEWORD(x,y)獲得,x:高,y:低。
- lpWSAData:一般以需要設(shè)置前面兩個成員即可。
- 參數(shù)
1.3 錯誤檢查和處理
int WSAGetLastError(void);
int WSASetLastError(void); // ?
1.3 協(xié)議尋址
- 協(xié)議
- IP:是一種無連接協(xié)議,不能確保數(shù)據(jù)傳輸?shù)某晒Γ?/li>
- TCP和UDP使用IP進(jìn)行面向連接和無連接的數(shù)據(jù)通信。所以稱作TCP/IP和UDP/TP。
- IPv4尋址
- 通過
SOCKADDR_IN
結(jié)構(gòu)來指定IP地址和服務(wù)端口信息。- sin_family字段必須設(shè)置為AF_INET,已告知Winsock此時正在使用IP地址族。
- sin_port定義端口。
- sin_addr保存IP地址。
-
inet_addr
函數(shù):把點(diǎn)分IP地址轉(zhuǎn)換成32位無符號長整數(shù)。 - 字節(jié)排序
-
big-endian
:字節(jié)的排序從最無意義的字節(jié)到最有意義的字節(jié); -
little-endian
:字節(jié)的排序從最有意義的字節(jié)到最無意義的字節(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é)序
-
- 通過
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ù):面向連接的通信和無連接的通信。
1.6 面向連接的通信
1.6.1 服務(wù)器API函數(shù)
1.6.1.1 綁定
一旦為某種協(xié)議創(chuàng)建了套接字,就必須將套接字綁定到一個已知的地址上。
-
bind函數(shù)
int bind( SOCKET s, // 等待客戶連接的服務(wù)器套接字 const struct sockaddr FAR* name, // 地址緩沖區(qū) int namelen );
-
bind常見錯誤
- WSAEADDRINUSE:如果是TCP/IP,那么說明另一個進(jìn)程已經(jīng)同本地IP接口及端口號綁定了,或者那個IP接口和端口號處于TIME_OUT狀態(tài)。
- WSAEFAULT:說明該套接字已被綁定。
1.6.1.2 監(jiān)聽
-
listen函數(shù)
int listen( SOCKET s,// 一個已經(jīng)被綁定的套接字 int backlog // 指定了被擱置的連接的對大隊列長度 );
backlog:
- 假定該參數(shù)為2,那么當(dāng)有3個客戶機(jī)同時發(fā)出請求,那么前面兩個會被放在一個“掛起”隊列中,而第三個連接請求會失敗。并返回WSAECONNREFUSED錯誤碼。
- 當(dāng)服務(wù)器接受了一個連接,那么該連接就會從隊列中刪除,以便別人可以繼續(xù)發(fā)出請求。
- 其本身也有限制,該限制是由下層的協(xié)議提供程序決定的。如果這個參數(shù)出現(xiàn)非法值,那么系統(tǒng)會用與之最接近的一個合法值來取代。但是如何找出實(shí)際的backlog值,還不存在一種標(biāo)準(zhǔn)的方案。
1.6.1.3 接受連接
-
accept函數(shù)
SOCKET accept( SOCKET s, // 一個已經(jīng)被綁定的套接字 struct socketaddr FAR* addr, int FAR* addrlen );
-
函數(shù)說明
- accept函數(shù)返回后,addr結(jié)構(gòu)中會包含發(fā)出連接請求的那個客戶機(jī)的IPv4地址信息,而addrlen參數(shù)則指出addr結(jié)構(gòu)的長度。
- accept函數(shù)會返回一個新的套接字描述符,對應(yīng)已經(jīng)被接受的那個客戶機(jī)連接。
1.6.2 客戶端API函數(shù)
客戶端創(chuàng)建步驟:
- 創(chuàng)建套接字;
- 建立一個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等。
- 套接字主動關(guān)閉以及被動關(guān)閉。
-
connect函數(shù)
int connect( SOCKET s, const struct socketaddr FAR* name, int namelen );
常見錯誤碼:
- WSAECONNREFUSED:想要連接的計算機(jī)沒有用于監(jiān)聽的進(jìn)程;
- WSAETIMEOUT:試圖連接的計算機(jī)不可用(也有可能是硬件故障,或主機(jī)沒有聯(lián)網(wǎng)等);
1.6.3 數(shù)據(jù)傳輸
常見錯誤:
- WSAECONNRESET:連接正在被關(guān)閉,可能是超時、通信方關(guān)閉連接。
- WSAEWOULDBLOCK:一般套接字處于非阻塞模式或異步狀態(tài)時會返回。
1.6.3.1 send
和WSASend
-
send函數(shù)
int send( SOCKET s, const char FAR* buf, int len, int flags );
常見錯誤
- WSAECONNABORTED:一般在虛擬回路由于超時或協(xié)議有錯而中斷是發(fā)生。此時表明該套接字不能在使用,應(yīng)將其關(guān)閉。
- WSAECONNRESET:遠(yuǎn)程主機(jī)上的應(yīng)用程序通過執(zhí)行強(qiáng)行關(guān)閉或意外中斷操作重新設(shè)置虛擬回路,或遠(yuǎn)程主機(jī)重新啟動。也需要關(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 );
常見錯誤
- WSAEMSGSIZE:當(dāng)掛起數(shù)據(jù)大于所提供的緩沖區(qū),緩沖區(qū)會盡量讓數(shù)據(jù)填滿。此時recv調(diào)用會產(chǎn)生該錯誤,但該錯誤只會在UDP協(xié)議出現(xiàn),TCP不會。
注意:慎用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ù)對UDP而言毫無意義,因?yàn)樗菬o連接的。
1.6.5.2 closesocket
函數(shù)
-
closesocket函數(shù)
int closesocket(SOCKET s);
1.7 無連接通信(UDP/IP)
UDP不能確保可靠的數(shù)據(jù)傳輸,但能將數(shù)據(jù)發(fā)送到多個目標(biāo),或者接受的多個源數(shù)據(jù)。
數(shù)據(jù)的傳輸使用數(shù)據(jù)報,即離散信息包。
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é)議
面向連接的通信同時也是流協(xié)議,無連接通信幾乎都是基于消息的。
-
收發(fā)數(shù)據(jù)考慮點(diǎn)
-
面向消息的協(xié)議保留了數(shù)據(jù)邊界,所以提交給發(fā)送函數(shù)的數(shù)據(jù)在發(fā)送完之前會形成阻塞。對非阻塞I/O模式而言,如果數(shù)據(jù)未能完全發(fā)送,發(fā)送函數(shù)就會返回WSAEWOULDBLOCK錯誤。需要再次調(diào)用發(fā)送函數(shù)。
記住:對于基于消息的協(xié)議而言,寫入操作只能作為一種自動行為發(fā)生。
連接的另一端,對接收函數(shù)的調(diào)用必須提供一個足夠大的緩沖空間。否則會出現(xiàn)WSAEMSGSIZE錯誤。此時緩沖區(qū)會被填滿,且未接收的數(shù)據(jù)會被丟棄。且無法恢復(fù)。(唯一特例是支持部分消息的協(xié)議)
-
多個網(wǎng)絡(luò)接口機(jī)器上發(fā)送UDP/IP消息問題。
UDP套接字不會真正和網(wǎng)絡(luò)接口綁定在一起,而是建立一種關(guān)聯(lián),即使用
bind
顯示綁定IP接口稱為發(fā)出去的UDP數(shù)據(jù)報的源IP地址。但是真正決定數(shù)據(jù)報在哪個物理接口上發(fā)送出去的,是路由表。意味著,如果先執(zhí)行顯式綁定,源IP地址就可能有誤,即源IP地址可能不是真正在它上面發(fā)送數(shù)據(jù)報的那個接口的IP地址。
書上并沒有把問題講清楚,需后續(xù)在查找資料。
-
1.7.4 釋放資源
本來就是無連接,對它不用太客氣,直接調(diào)用closesocket
函數(shù)即可。
1.8 其他API函數(shù)
1.8.1 getpeername
函數(shù)
用于獲取通信方的套接字地址信息。
1.8.2 getsockname
函數(shù)
該函數(shù)對應(yīng)getpeername
函數(shù)。返回給定套接字的本地接口地址信息。
1.8.3 WSADuplicateSocket
函數(shù)(套接字復(fù)制函數(shù))
用于建立WSAPROTOCOL_INFO結(jié)構(gòu),該結(jié)構(gòu)可以傳遞至另一個進(jìn)程。這樣另一個進(jìn)程打開指向同一個下層套接字的句柄,如此一來,這個進(jìn)程也能對該資源進(jìn)行操作。
該函數(shù)生成的套接字描述符被稱為共享套接字描述符。
注意點(diǎn):
- 需考慮進(jìn)程間通信問題;
- 需考慮I/O同步問題;
- 使用該函數(shù)復(fù)制出的描述符的進(jìn)程關(guān)閉該套接字,不會影響其他進(jìn)程。直到最后一個描述符調(diào)用關(guān)閉套接字之前,下層套接字依然保持打開狀態(tài)。
- 利用任何一個共享描述符執(zhí)行
WSAAsyncSelect
函數(shù)或WSAEventSelect
函數(shù)時,都會刪除以前所有的套接字事件注冊。
1.9 Windows CE
2 設(shè)計Winsock
2.1 系統(tǒng)體系結(jié)構(gòu)
提供程序:具體執(zhí)行應(yīng)用程序的Winsock API調(diào)用的程序。具體調(diào)用哪個提供程序,由WS2_32.dll確定。
-
提供程序分類
基礎(chǔ)提供程序:位于傳輸層頂端
-
分層提供程序:
位于WS2_32.dll之下,基礎(chǔ)提供程序之上;
-
能截獲并操縱Winsock調(diào)用;
如果應(yīng)用程序利用分層提供程序創(chuàng)建了一個套接字,分層提供程序?qū)⑹褂迷撎捉幼纸孬@所有的Winsock調(diào)用。分層提供程序可能會阻塞、修改調(diào)用,也可能將未修改的調(diào)用傳遞給底層的提供程序。
2.2 協(xié)議的特征
2.2.1 面向消息
如果某種協(xié)議將字節(jié)當(dāng)做一條獨(dú)立的消息在網(wǎng)上傳輸,則稱該協(xié)議是面向消息的。如UDP。
保留消息邊界:發(fā)送端向接收端發(fā)送三個數(shù)據(jù)報,接收端在第一次接收時,并不會把所有的三個數(shù)據(jù)報返回,即使它已經(jīng)全部接收。
2.2.1 面向流
不保留消息邊界的協(xié)議通常被稱作“基于流的協(xié)議”。
流服務(wù)的定義是連續(xù)的數(shù)據(jù)傳輸;
- 對于接收端:不管消息邊界是否存在,接收端都會盡量的讀取有效數(shù)據(jù);只要數(shù)據(jù)一到達(dá)網(wǎng)絡(luò)堆棧,網(wǎng)絡(luò)堆棧就開始讀取它,并將它放在緩沖區(qū)中等待進(jìn)程處理。
- 對于發(fā)送端:系統(tǒng)會將原始消息分解成小消息或者把幾條消息積累在一起,并形成一個較大的數(shù)據(jù)包。
2.2.3 偽流
對于發(fā)送端:依然是發(fā)送離散消息;跟面向消息一樣。
對于接收端:將接收到的數(shù)據(jù)放在緩沖池中,接收應(yīng)用程序可隨意讀取;類似面向流。
2.2.4 面向連接和無連接
通常,一個協(xié)議要么提供面向連接的服務(wù),要么提供無連接的服務(wù)。
- 面向連接:進(jìn)行數(shù)據(jù)交換之前必須建立一條路徑。
- 無連接:不在乎接收端是否在偵聽,直接發(fā)。
2.2.5 可靠性和有序性
面向連接可靠性高,也可保證有序性。但是二者不可兼得。
2.2.6 正常關(guān)閉
只出現(xiàn)在面向連接的協(xié)議中。
2.2.7 廣播數(shù)據(jù)
即從一個工作站發(fā)出的數(shù)據(jù),局域網(wǎng)內(nèi)的所有工作站都能收到。
2.2.8 多播數(shù)據(jù)
指一個進(jìn)程發(fā)送數(shù)據(jù)而一個或多個接收端可以接收到數(shù)據(jù)的能力。
2.2.9 服務(wù)質(zhì)量
體現(xiàn)了應(yīng)用程序請求獨(dú)占網(wǎng)絡(luò)帶寬的能力。
2.2.10 部分消息
只用于面向消息的協(xié)議。
2.2.11 路由選擇的考慮
路由器會直接丟棄非路由協(xié)議數(shù)據(jù)包,即使兩臺機(jī)器連接在同一路由器。
2.2.12 其他特征
2.3 Winsock編錄(Winsock目錄)
Winsock編錄是一個數(shù)據(jù)庫,它包含系統(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)建套接字
- 多個提供程序可以共享一個地址族、套接字類型及協(xié)議。需使用
WSASocket
函數(shù)代替socket
函數(shù)。
3 網(wǎng)際協(xié)議
3.1 IPv4
3.1.1 尋址
-
IPv4地址分類
種類 網(wǎng)絡(luò)部分 第1個數(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ī)。
3.1.1.1 單播
分配到單個計算機(jī)接口上的地址稱為單播地址,該地址僅可以分配到一個接口上。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é)議
將一個32位IPv4地址解析為一個物理地址或硬件地址,使用IPv4數(shù)據(jù)包能夠被包裝在適當(dāng)?shù)拿襟w幀中。
- 如果目標(biāo)地址位于局域網(wǎng)內(nèi),則ARP請求將針對目的地的物理地址。
- 如果一個或者多個路由器將源和目的地分離開來,則ARP請求將針對缺省網(wǎng)關(guān),數(shù)據(jù)包也將發(fā)往該網(wǎng)關(guān)。
-
ICMP(Internet Control Message Protocol):Internet控制信息協(xié)議
目的是為了在IPv4主機(jī)之間發(fā)送狀態(tài)信息和錯誤信息。也被用來搜尋鄰近路由器。
-
IGMP(Internet, Management Protocol):Internet組管理協(xié)議
用來管理多播組的成員。
3.1.3 Winsock中的IPv4尋址
- 端口號分類
- 0~1023:由IANA控制,為已知服務(wù)所保留;
- 1024~49151:已注冊端口號,由普通用戶執(zhí)行的普通用戶進(jìn)程或程序可以使用這些端口;
- 49152~65535:動態(tài)和(或)專用端口。
- 如果沒有顯示綁定端口號,系統(tǒng)會把套接字隱式地綁定到1024~5000范圍內(nèi)的一個本地端口上。
3.2 IPv6
-
NAT(Network Address Translators):網(wǎng)絡(luò)地址轉(zhuǎn)換器。
將多個專用地址映射到單個的公共IP地址上。
該節(jié)略。
3.3 地址及名稱解析
3.3.1 名稱解析例程
-
名稱解析函數(shù)
getnameinfo
函數(shù)和getaddrinfo
函數(shù):可以兼容IPv4和IPv6,用以代替gethostbyname
函數(shù)和inet_addr
函數(shù)。 使用:包含
WS2TCPIP.H
頭文件,并在其之前包含WSPIAPI.H
頭文件。
該章略過,后面主要講述一些使用新函數(shù)的示例代碼。
4 Winsock支持的其他協(xié)議(略過)
5 WinsockI/O方法
5.1 套接字模式
5.1.1 阻塞模式
I/O操作完成前,執(zhí)行操作的Winsock調(diào)用會一直等待下去。
5.1.2 非阻塞模式
Winsock函數(shù)無論如何都會立即返回。
5.2 套接字I/O模型
5.2.1 阻塞模型
優(yōu)點(diǎn):簡潔;
缺點(diǎn):浪費(fèi)資源,難以擴(kuò)展到很多連接的情況。
5.2.2 select模型
工作原理是利用select
函數(shù)實(shí)現(xiàn)對I/O的管理。
優(yōu)點(diǎn):從單個線程的多套接字上進(jìn)行多重連接及I/O操作。避免阻塞模式的線程劇增。
缺點(diǎn):也是單線程的缺點(diǎn)一般最大不超過1024的套接字。
5.2.3 WSAAsyncSelect模型
消息通知:應(yīng)用程序可在一個套接字上接收以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ò)事件時接收的消息 long lEvent // 代表一個掩碼,指定一系列網(wǎng)絡(luò)事件的組合 );
注意:
- 多個事件必須在套接字上一次完成注冊;
- 除非明確調(diào)用
closesocket
函數(shù),或者調(diào)用WSAAsyncSelect
函數(shù)更改注冊的網(wǎng)絡(luò)事件,否則,時間通知總是有效; - 將
lEvent
參數(shù)置為0,則效果相當(dāng)于停止在套接字上進(jìn)行的所有網(wǎng)絡(luò)事件。
調(diào)用
WSAAsyncSelect
函數(shù)后,套接字的模式會從阻塞模式自動變成非阻塞模式。-
FD_WRITE發(fā)出條件:
- 使用```connect``或者WSAConnect,一個套接字首次建立連接;
- 使用accept或者WSAAccept,套接字被接受以后;
- 若send、WSASend、sendto或WSASendTo操作失敗,返回了WSAEWOULDBLOCK錯誤,而且緩沖區(qū)的空間變得可用。
優(yōu)點(diǎn):在系統(tǒng)開銷不大的情況下同時處理許多連接。
缺點(diǎn):即使應(yīng)用程序不需要窗口,也必須創(chuàng)建一個窗口;且一個窗口處理成千上萬的套接字中的所有事件,性能成為瓶頸。
5.2.4 WSAEventSelect模型
事件通知:通過事件對象句柄完成網(wǎng)絡(luò)事件處理。
-
步驟
// 創(chuàng)建事件對象(人工重設(shè)事件對象) // 兩種工作狀態(tài):signaled/non-signaled // 兩種工作模式:manualreset/autoreset WSAEVENT WSACreEvent(void); // 注冊事件消息通知 int WSAEventSelect( SOCKET s, WSAEVENT hEventObject, long lNetWorkEvents ); // 修改事件工作狀態(tài) BOOL WSAResetEvent(void); // 關(guān)閉事件 BOOL WSACloseEvent(WSAEVENT hEvent); // 等待一個或多個網(wǎng)絡(luò)事件對象句柄 DWORD WSAWaitForMultiEvent( DWORD cEvents, const WSAEVENT FAR* lphEvent, BOOL fWaitAll, DWORD dwTimeout, BOOL fAlertable );
優(yōu)點(diǎn):概念簡單;不需要窗口環(huán)境。
缺點(diǎn):最多只支持64個事件。擴(kuò)充只能通過住址線程池解決。
5.2.5 重疊模型(該節(jié)略過)
可通過ReadFile和WriteFile兩個函數(shù)實(shí)現(xiàn)在設(shè)備上執(zhí)行I/O操作。但是考慮到跨平臺性,建議使用WSARecv和WSASend函數(shù)。
- 步驟
- 創(chuàng)建套接字;
- 將套接字與本地接口綁定;
- 可通過事件對象通知和完成例程來管理重疊I/O請求的完成情況。
5.2.5.1 事件通知
要求將Windows事件對象與WSAOVERLAPPED結(jié)構(gòu)關(guān)聯(lián)。
5.2.6 完成端口模型(該節(jié)略過)
6 可伸縮的Winsock應(yīng)用程序(略過)
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 套接字選項和I/O控制指令
7.1 套接字選項
7.1.1 SOL_SOCKET選項級別
7.1.2 SOL_APPLETALK選項級別
7.1.3 SOL_IRLMP選項級別
7.1.4 IPPROTO_IP選項級別
7.1.5 IPPROTO_IPV6選項級別
7.1.6 IPPROTO_RM選項級別
7.1.7 IPPROTO_TCP選項級別
7.1.8 NSPROTO_IPX選項級別
7.2 IOCTLSOCKET、WSAIOCTL和WSANSPloctl
8 名稱注冊和解析
8.1 背景知識
名稱注冊是一個過程,它把一個用戶友好的名稱和具體協(xié)議地址關(guān)聯(lián)在一起。
8.2 命名空間模型
- 命名空間提供用一個友好名把具體的協(xié)議及其尋址屬性關(guān)聯(lián)在一起的功能。如針對IP的DNS。
- 分類
- 動態(tài)命名空間:允許實(shí)時注冊服務(wù);
- 靜態(tài)命名空間:須手動注冊,無法使用Winsock用它來注冊服務(wù)名;
- 固定命名空間:允許實(shí)時注冊服務(wù);和動態(tài)命名空間不同的是它把注冊信息保留在固定地方。
- WSAEnumNameSpaceProvider:獲取系統(tǒng)上所有的命名空間。
8.3 服務(wù)的注冊
需要利用命名空間提供程序注冊服務(wù)。
服務(wù)類**:描述哪些命名空間可用來注冊服務(wù);
服務(wù):服務(wù)是啥???TODO
8.3.1 安裝服務(wù)類
函數(shù):WSAInstallServiceClass
8.3.2 服務(wù)的注冊
函數(shù):WSASetService
8.3.3 服務(wù)注冊示例
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 背景知識
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 原始套接字
利用原始套接字可以訪問位于基層的傳輸層協(xié)議。利用原始套接字來模擬IP的一些實(shí)用程序,如Traceroute和Ping等。
11.1 創(chuàng)建原始套接字
11.2 ICMP
便于不同主機(jī)之間傳遞消息的一種機(jī)制。
11.2.1 Ping示例
11.2.2 Traceroute示例
11.3 使用IP頭包含選項
12 Winsock服務(wù)提供程序接口(SPI)
- 分類
-
傳輸服務(wù)提供程序
-
分層服務(wù)提供程序:
- 會將自己安裝在Winsock編目里,并位于基礎(chǔ)服務(wù)提供程序之上,可能位于其他分層提供程序之間。
- 截獲應(yīng)用程序?qū)insock API調(diào)用;
- 如果應(yīng)用程序創(chuàng)建的套接字和某個分層提供程序的特征匹配,則該分層服務(wù)提供程序就會被調(diào)用。
- 基礎(chǔ)服務(wù)提供程序:公開一個Winsock接口,直接執(zhí)行一種協(xié)議。
-
分層服務(wù)提供程序:
-
命名空間提供程序
- 類似傳輸服務(wù)提供程序,只是它截獲的是名稱解析的Winsock API調(diào)用,如gethostbyname或WSALookupServiceBegin;
- 將自己安裝在命名空間編錄中,當(dāng)應(yīng)用程序執(zhí)行的名稱解析搜索和它匹配時,命名空間提供程序就會被調(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)一個錯誤,就極有可能使所有訪問Winsock位于LSP下邊的協(xié)議的應(yīng)用程序崩潰。如果發(fā)生在IP上,則注入LSASS之類的關(guān)鍵性服務(wù)都會停止。
- 解決:必須重啟計算機(jī),進(jìn)入安全模式,并卸載LSP,就可以將Winsock編錄恢復(fù)回正常狀態(tài)。
- 比較好的做法是在重啟系統(tǒng)之前對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ù)
15.1 RAS客戶機(jī)
15.2 編譯和鏈接
15.3 數(shù)據(jù)結(jié)構(gòu)和平臺兼容性問題
15.4 DUN1.3升級和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