![《網(wǎng)絡(luò)工程設(shè)計(jì)與實(shí)踐》課件第12章_第1頁](http://file4.renrendoc.com/view12/M04/36/2F/wKhkGWbEk_aALN9KAAGbBivM6sM188.jpg)
![《網(wǎng)絡(luò)工程設(shè)計(jì)與實(shí)踐》課件第12章_第2頁](http://file4.renrendoc.com/view12/M04/36/2F/wKhkGWbEk_aALN9KAAGbBivM6sM1882.jpg)
![《網(wǎng)絡(luò)工程設(shè)計(jì)與實(shí)踐》課件第12章_第3頁](http://file4.renrendoc.com/view12/M04/36/2F/wKhkGWbEk_aALN9KAAGbBivM6sM1883.jpg)
![《網(wǎng)絡(luò)工程設(shè)計(jì)與實(shí)踐》課件第12章_第4頁](http://file4.renrendoc.com/view12/M04/36/2F/wKhkGWbEk_aALN9KAAGbBivM6sM1884.jpg)
![《網(wǎng)絡(luò)工程設(shè)計(jì)與實(shí)踐》課件第12章_第5頁](http://file4.renrendoc.com/view12/M04/36/2F/wKhkGWbEk_aALN9KAAGbBivM6sM1885.jpg)
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
第12章WinSock網(wǎng)絡(luò)程序設(shè)計(jì)12.1WinSock的基本情況
12.2套接字編程基本概念
12.3Sockets庫函數(shù)
12.4典型套接字系統(tǒng)調(diào)用時(shí)序圖
12.5WindowsSockets對(duì)BerkeleySockets的擴(kuò)充
12.6基于WinSock函數(shù)的網(wǎng)絡(luò)應(yīng)用程序開發(fā)12.7使用面向?qū)ο蟮拈_發(fā)語言提供的與網(wǎng)絡(luò)通信相關(guān)的類開發(fā)網(wǎng)絡(luò)應(yīng)用程序12.8使用可視化開發(fā)工具的網(wǎng)絡(luò)控件開發(fā)網(wǎng)絡(luò)應(yīng)用程序
12.1WinSock的基本情況
在Windows下的各種網(wǎng)絡(luò)編程接口中,WindowsSockets脫穎而出,越來越得到大家的重視,這是因?yàn)閃indowsSockets規(guī)范是一套開放的、支持多協(xié)議的Windows下的網(wǎng)絡(luò)編程接口。從1991年的1.0版本到1995年的2.0.8版本,WindowsSockets經(jīng)過不斷完善并在Intel、Microsoft、Sun、SGI、Informix、Novell等公司的全力支持下,已經(jīng)成為Windows網(wǎng)絡(luò)編程事實(shí)上的標(biāo)準(zhǔn)。
WindowsSocketsAPI是MicrosoftWindows的網(wǎng)絡(luò)程序接口,它包括一個(gè)標(biāo)準(zhǔn)的BerkeleySockets功能調(diào)用的集合,以及為Windows所做的重要擴(kuò)充。擴(kuò)充的功能調(diào)用都以WSA(WindowsSocketsAsynchronous)作前綴,表明它們?cè)试S異步的I/O操作,并采用了符合Windows消息機(jī)制的網(wǎng)絡(luò)事件異步選擇機(jī)制。這些擴(kuò)充有利于應(yīng)用程序開發(fā)者更好地利用Windows的消息驅(qū)動(dòng)特性,設(shè)計(jì)出高性能的網(wǎng)絡(luò)程序。
WindowsSockets的實(shí)現(xiàn)一般都由兩部分組成:開發(fā)組件和運(yùn)行組件。開發(fā)組件是供程序員開發(fā)WindowsSockets應(yīng)用程序使用的,包括介紹WindowsSockets實(shí)現(xiàn)的文檔、WindowsSockets應(yīng)用程序接口(API)引入庫和一些頭文件。頭文件WINSOCK.H是WindowsSockets最重要的頭文件,包括了WindowsSockets實(shí)現(xiàn)所定義的宏、常數(shù)值、數(shù)據(jù)結(jié)構(gòu)和函數(shù)調(diào)用接口類型。運(yùn)行組件是WindowsSockets應(yīng)用程序接口的動(dòng)態(tài)連接庫(DLL),文件名為WINSOCK.DLL,應(yīng)用程序在執(zhí)行時(shí)通過裝入它實(shí)現(xiàn)網(wǎng)絡(luò)通信功能。
12.2套接字編程基本概念
12.2.1套接字
套接字(Socket)是網(wǎng)絡(luò)通信的基本構(gòu)件,是可以被命名和尋址的通信端點(diǎn),使用中的每一個(gè)套接字都有其類型和一個(gè)與之相連的進(jìn)程。
套接字存在于通信區(qū)域中。通信區(qū)域也稱為地址族,是一個(gè)抽象概念,主要用于把通過套接字通信的進(jìn)程的共有特性綜合在一起。套接字通常只與同一區(qū)域中的套接字交換數(shù)據(jù)(也可跨區(qū)域通信,但要執(zhí)行某種轉(zhuǎn)換進(jìn)程之后才能實(shí)現(xiàn))。WindowsSockets只支持一個(gè)通信區(qū)域:網(wǎng)際域(AF-INET),這個(gè)域被使用網(wǎng)際協(xié)議族通信的進(jìn)程使用。套接字都具有類型,是根據(jù)用戶可見的通信特征進(jìn)行分類的。應(yīng)用程序被假定為只在同一類型的套接字間通信,不過只要通信協(xié)議支持,也可在不同類型的套接字間通信。
TCP/IP的Socket提供三種類型的套接字:
(1)流式套接字(SOCK_STREAM):提供一個(gè)面向連接的、可靠的數(shù)據(jù)傳輸服務(wù),數(shù)據(jù)無差錯(cuò)、無重復(fù)地發(fā)送,且按發(fā)送順序接收。內(nèi)設(shè)流量控制,避免數(shù)據(jù)流超限;數(shù)據(jù)被看作是字節(jié)流,無長度限制。文件傳送協(xié)議(FTP)即使用流式套接字。
(2)數(shù)據(jù)報(bào)式套接字(SOCK_DGRAM):提供一個(gè)無連接服務(wù)。數(shù)據(jù)包以獨(dú)立包形式被發(fā)送,不提供無錯(cuò)保證,數(shù)據(jù)可能丟失、重復(fù)或接收順序混亂。網(wǎng)絡(luò)文件系統(tǒng)(NFS)使用數(shù)據(jù)報(bào)式套接字。
(3)原始式套接字(SOCK_RAW):該接口允許對(duì)較低層協(xié)議(如IP、ICMP)直接訪問。常用于檢驗(yàn)新的協(xié)議實(shí)現(xiàn)或訪問現(xiàn)有服務(wù)中配置的新設(shè)備。12.2.2網(wǎng)間進(jìn)程通信
1.端口
網(wǎng)絡(luò)中可以被命名和尋址的通信端口是操作系統(tǒng)可分配的一種資源。按照OSI協(xié)議的描述,傳輸層與網(wǎng)絡(luò)層在功能上的最大區(qū)別是傳輸層提供進(jìn)程通信能力。從這個(gè)意義上講,網(wǎng)絡(luò)通信的最終地址不僅僅是主機(jī)地址,還包括可以描述進(jìn)程的某種標(biāo)識(shí)符。為此,TCP/IP協(xié)議提出了協(xié)議端口(protocolport,簡稱端口)的概念,用于標(biāo)識(shí)通信的進(jìn)程。端口是一種抽象的軟件結(jié)構(gòu)(包括一些數(shù)據(jù)結(jié)構(gòu)和I/O緩沖區(qū))。應(yīng)用程序(進(jìn)程)通過系統(tǒng)調(diào)用與某端口建立連接(binding)后,傳輸層傳給該端口的數(shù)據(jù)都被相應(yīng)進(jìn)程所接收,相應(yīng)進(jìn)程發(fā)給傳輸層的數(shù)據(jù)都通過該端口輸出。在TCP/IP協(xié)議的實(shí)現(xiàn)中,端口操作類似一般的I/O操作,進(jìn)程獲取一個(gè)端口,相當(dāng)于獲取本地惟一的I/O文件,可以用一般的讀寫原語訪問。
類似于文件描述符,每個(gè)端口都擁有一個(gè)叫端口號(hào)(portnumber)的整數(shù)型標(biāo)識(shí)符,用于區(qū)別不同的端口。由于TCP/IP傳輸層的兩個(gè)協(xié)議TCP和UDP是完全獨(dú)立的兩個(gè)軟件模塊,因此各自的端口號(hào)也相互獨(dú)立。端口號(hào)的分配是個(gè)重要問題,有兩種基本分配方式:全局分配和本地分配。全局分配是一種集中控制方式,由一個(gè)公認(rèn)的中央機(jī)構(gòu)根據(jù)用戶需要進(jìn)行統(tǒng)一分配,并將結(jié)果公布于眾。本地分配又稱動(dòng)態(tài)鏈接,即進(jìn)程需要訪問傳輸層服務(wù)時(shí),向本地操作系統(tǒng)提出申請(qǐng),操作系統(tǒng)返回一個(gè)本地惟一的端口號(hào),進(jìn)程再通過合適的系統(tǒng)調(diào)用,將自己與該端口號(hào)聯(lián)系起來。TCP/IP中端口號(hào)的分配綜合了上述兩種方式。TCP/IP將端口號(hào)分為兩部分,少量的作為保留端口,以全局方式分配給服務(wù)進(jìn)程,因此每個(gè)標(biāo)準(zhǔn)服務(wù)器都擁有一個(gè)全局公認(rèn)的端口即周知端口(well-knownport),即使在不同機(jī)器上,其端口號(hào)也相同。剩余的為自由端口,以本地方式進(jìn)行分配。TCP和UDP均規(guī)定,小于256的端口號(hào)才能作為保留端口。
2.地址
網(wǎng)絡(luò)通信中通信的兩個(gè)進(jìn)程在不同的機(jī)器上。這兩個(gè)機(jī)器可能位于不同的網(wǎng)絡(luò),這些網(wǎng)絡(luò)通過網(wǎng)絡(luò)互聯(lián)設(shè)備(網(wǎng)關(guān)、網(wǎng)橋、路由器等)連接。因此需要三級(jí)尋址:
(1)某一主機(jī)與多個(gè)網(wǎng)絡(luò)相連,必須指定一特定網(wǎng)絡(luò)地址。
(2)網(wǎng)絡(luò)上每一主機(jī)應(yīng)有惟一的地址。
(3)每一主機(jī)上的每一進(jìn)程應(yīng)有在該主機(jī)上的惟一標(biāo)識(shí)符。
通常主機(jī)地址由網(wǎng)絡(luò)ID和主機(jī)ID組成,在TCP/IP協(xié)議中用32位整數(shù)值表示;TCP和UDP均使用16位端口號(hào)標(biāo)識(shí)用戶進(jìn)程。
3.網(wǎng)絡(luò)字節(jié)順序
不同計(jì)算機(jī)存放多字節(jié)值的順序不同。為保證數(shù)據(jù)的正確性,在網(wǎng)絡(luò)協(xié)議中需要指定網(wǎng)絡(luò)字節(jié)順序。TCP/IP協(xié)議使用16位整數(shù)和32位整數(shù)的高價(jià)先存(高位字節(jié)在前,低位字節(jié)在后)格式,它們均含在協(xié)議頭文件中。
4.連接
兩個(gè)進(jìn)程間的通信鏈路稱為連接。連接在內(nèi)部表現(xiàn)為一些緩沖區(qū)和一組協(xié)議機(jī)制,在外部表現(xiàn)出比無連接高的可靠性。
5.半相關(guān)
網(wǎng)絡(luò)中用協(xié)議、本地地址、本地端口號(hào)三者構(gòu)成的一個(gè)三元組在全局中惟一標(biāo)志一個(gè)進(jìn)程。這個(gè)三元組叫半相關(guān)(half-association),它指定連接一邊的進(jìn)程部分。
6.全相關(guān)
一個(gè)完整的網(wǎng)間進(jìn)程通信需要兩個(gè)進(jìn)程組成,且只能使用同一種高層協(xié)議。即不可能通信的一端用TCP協(xié)議通信,另一端用UDP協(xié)議通信。因此一個(gè)完整的網(wǎng)間通信需要一個(gè)五元組來標(biāo)識(shí)(協(xié)議,本地地址,本地端口號(hào),遠(yuǎn)端地址,遠(yuǎn)端端口號(hào)),這個(gè)五元組叫相關(guān)或全相關(guān)(association),即兩個(gè)協(xié)議相同的半相關(guān)才能組成一個(gè)合適的相關(guān),或完全指定組成一個(gè)連接。12.2.3服務(wù)方式
1.面向連接(虛電路)或無連接
面向連接服務(wù)是電話系統(tǒng)服務(wù)模式的抽象,每一次完整的數(shù)據(jù)傳輸都要經(jīng)過建立連接、使用連接、中止連接的過程。在數(shù)據(jù)傳輸過程中,各數(shù)據(jù)分組,但不攜帶目的地址,而是使用連接號(hào)(connectID)。本質(zhì)上,連接是一個(gè)管道,收發(fā)數(shù)據(jù)不但順序一致,而且內(nèi)容相同。TCP協(xié)議提供面向連接的虛電路。
無連接服務(wù)是郵政系統(tǒng)服務(wù)模式的抽象,每個(gè)分組都攜帶完整的目的地址,各分組在系統(tǒng)中獨(dú)立傳送。無連接服務(wù)不能保證分組的先后順序,不進(jìn)行分組出錯(cuò)的恢復(fù)和重傳,不保證傳輸?shù)目煽啃浴DP協(xié)議提供無連接的數(shù)據(jù)報(bào)服務(wù)。
2.順序
在網(wǎng)絡(luò)傳輸中,兩個(gè)連續(xù)報(bào)文在端到端通信中可能經(jīng)過不同的路徑,這樣到達(dá)目的地址時(shí)的順序可能會(huì)與發(fā)送時(shí)不同?!绊樞颉笔侵附邮諗?shù)據(jù)順序與發(fā)送數(shù)據(jù)順序相同。TCP協(xié)議提供這項(xiàng)服務(wù)。
3.差錯(cuò)控制
差錯(cuò)控制是保證應(yīng)用程序接收的數(shù)據(jù)無差錯(cuò)的一種機(jī)制。檢查差錯(cuò)的方法一般是采用檢驗(yàn)“檢查和(Checksum)”的方法。而保證傳輸無差錯(cuò)的方法是雙方采用確認(rèn)應(yīng)答技術(shù)。TCP協(xié)議提供這項(xiàng)服務(wù)。
4.流控制
流控制是在數(shù)據(jù)傳輸過程中控制數(shù)據(jù)傳輸速率的一種機(jī)制,以保證數(shù)據(jù)不丟失。TCP協(xié)議提供這項(xiàng)服務(wù)。
5.字節(jié)流
字節(jié)流方式是指僅把傳輸中的報(bào)文看作是一個(gè)字節(jié)序列,不提供數(shù)據(jù)流的任何邊界。TCP協(xié)議提供這項(xiàng)服務(wù)。
6.報(bào)文
接收方要保存發(fā)送方的報(bào)文邊界。UDP協(xié)議提供這項(xiàng)服務(wù)。
7.全雙工/半雙工
端與端之間的數(shù)據(jù)同時(shí)以兩個(gè)方向或一個(gè)方向傳送。
8.緩存/帶外數(shù)據(jù)
在字節(jié)流服務(wù)中,由于沒有報(bào)文邊界,用戶進(jìn)程在某一時(shí)刻可以讀寫任意數(shù)量的字節(jié)。采用有流控制的協(xié)議時(shí)或?yàn)楸WC傳輸正確時(shí),要進(jìn)行緩存。但對(duì)某些特殊的需求,如交互式應(yīng)用程序,又會(huì)要求取消這種緩存。
在數(shù)據(jù)傳輸過程中,希望不通過常規(guī)傳輸方式傳送給用戶以便用戶及時(shí)處理的一類信息稱為帶外數(shù)據(jù)。為了將互操作中的問題減到最小,應(yīng)用程序編寫者除非與現(xiàn)有服務(wù)互操作時(shí)要求帶外數(shù)據(jù),否則最好不要使用它。12.2.4客戶機(jī)/服務(wù)器模式
客戶機(jī)/服務(wù)器模式在操作過程中采取主動(dòng)請(qǐng)求方式。首先是服務(wù)器方要先啟動(dòng),并根據(jù)請(qǐng)求提供相應(yīng)的服務(wù),具體操作如下:
(1)打開一通信通道并告知本地主機(jī),它愿意在某公認(rèn)地址上接收客戶請(qǐng)求。
(2)等待客戶請(qǐng)求到達(dá)該端口。
(3)接收到重復(fù)服務(wù)請(qǐng)求。處理該請(qǐng)求并發(fā)送應(yīng)答信號(hào)。
(4)返回第二步,等待另一客戶請(qǐng)求。
(5)關(guān)閉服務(wù)器。客戶方的具體操作如下:
(1)打開一通信通道,并連接到服務(wù)器所在地主機(jī)的特定端口。
(2)向服務(wù)器發(fā)送服務(wù)請(qǐng)求報(bào)文,等待并接收應(yīng)答。
(3)請(qǐng)求結(jié)束后關(guān)閉通信通道并中止。
從上面描述的過程可知:
(1)客戶與服務(wù)器進(jìn)程的作用是非對(duì)稱的,因此編碼不同。
(2)服務(wù)進(jìn)程一般是先于客戶請(qǐng)求而啟動(dòng)的,只要系統(tǒng)運(yùn)行,該服務(wù)進(jìn)程一直存在,直到正常中止或強(qiáng)迫中止。
12.3Sockets庫函數(shù)
12.3.1庫函數(shù)綜述
1.套接字函數(shù)
WindowsSockets1.1版本支持的Sockets函數(shù)如表12.1所示。表12.1WindowsSockets1.1版本中的Sockets函數(shù)這些函數(shù)根據(jù)功能的不同可以分為如下幾類:
(1)套接字函數(shù)。此類函數(shù)包括sockets()、bind()、getpeername()、getsockname()和closesocket(),它們主要完成創(chuàng)建、關(guān)閉套接字功能,以及對(duì)套接字命名與名字獲取。
(2)網(wǎng)絡(luò)連接函數(shù)。此類函數(shù)包括listen()、accept()、connect()和shutdown(),它們完成網(wǎng)絡(luò)連接(如虛電路)的建立與關(guān)閉。此類函數(shù)中有部分可能阻塞。
(3)數(shù)據(jù)傳輸函數(shù)。此類函數(shù)包括send()、recv()、sendto()和recvfrom(),它們完成網(wǎng)絡(luò)數(shù)據(jù)的發(fā)送與接收,全部是可以阻塞的函數(shù)。
(4)字節(jié)定序函數(shù)。此類函數(shù)包括htonl()、htons()、ntohl()和ntohs(),它們完成主機(jī)和網(wǎng)絡(luò)之間數(shù)據(jù)字節(jié)順序的轉(zhuǎn)換。
(5)地址轉(zhuǎn)換函數(shù)。此類函數(shù)包括inet_addr()、inet_ntoa(),它們完成網(wǎng)絡(luò)字符串地址和Internet地址之間的轉(zhuǎn)換。
(6)套接字控制函數(shù)。此類函數(shù)包括getsockopt()、setsockopt()、ioctlsocket()和select(),它們?cè)O(shè)置/獲取套接字的選項(xiàng),控制/檢測套接字的工作狀態(tài)。其中select()函數(shù)在必要時(shí)可能阻塞。套接字默認(rèn)的工作模式是處于阻塞方式,一個(gè)阻塞操作可能阻塞整個(gè)Windows環(huán)境。在非搶占式優(yōu)先的Windows環(huán)境中,建議使用非阻塞(異步)操作。也就是說,推薦使用WindowsSockets提供的異步選擇函數(shù)代替可能阻塞的select()函數(shù),并且用網(wǎng)絡(luò)事件消息來驅(qū)動(dòng)可能阻塞的網(wǎng)絡(luò)連接函數(shù)(accept()和connect())數(shù)據(jù)傳輸函數(shù)。這樣設(shè)計(jì)的Windows程序能更好地工作。
2.數(shù)據(jù)庫函數(shù)
WindowsSockets定義了如表12.2所示的數(shù)據(jù)庫函數(shù)。表12.2WindowsSockets1.1版本定義的數(shù)據(jù)庫函數(shù)提供這類函數(shù)的目的是為了獲取網(wǎng)絡(luò)特定的信息。在WindowsSockets實(shí)現(xiàn)中,可能使用了不依賴于本地?cái)?shù)據(jù)庫文件的方法(如域名服務(wù)),但是對(duì)應(yīng)用程序來說,請(qǐng)求這些信息的格式是一致的,并且對(duì)應(yīng)用程序來說是透明的。
調(diào)用這些例程所獲得的信息存放在由WindowsSockets實(shí)現(xiàn)分配的一個(gè)結(jié)構(gòu)中,函數(shù)返回此結(jié)構(gòu)的地址。因此,應(yīng)用程序可以通過此結(jié)構(gòu)指針獲取所需要的信息,但它不能修改此結(jié)構(gòu),也不能釋放結(jié)構(gòu)的任一部分。另外,對(duì)一個(gè)線程來說,WindowsSockets實(shí)現(xiàn)只分配了結(jié)構(gòu)的一個(gè)備份,任何WindowsSocketsAPI調(diào)用都可以修改此結(jié)構(gòu)。也就是說,結(jié)構(gòu)指針指向的數(shù)據(jù)只在此線程的下一次WindowsSocketsAPI調(diào)用之前才是正確的,應(yīng)用程序應(yīng)該在發(fā)布任何其他WindowsSocketsAPI調(diào)用之前將任何需要的信息拷貝出來。
數(shù)據(jù)庫函數(shù)除了gethostname()之外都是阻塞的。在設(shè)計(jì)實(shí)現(xiàn)WindowsSockets應(yīng)用程序時(shí),建議使用WindowsSockets提供的數(shù)據(jù)庫函數(shù)的異步版本(見下節(jié))。
3.?WindowsSockets專用的增設(shè)函數(shù)
WindowsSockets針對(duì)BerkeleySockets標(biāo)準(zhǔn)函數(shù)集提供了一些擴(kuò)充,這些擴(kuò)充主要用于允許對(duì)網(wǎng)絡(luò)事件基于消息的異步存取。除了WSAStartup()和WSACleanup()函數(shù)之外,其他擴(kuò)充的函數(shù)對(duì)于基于套接字的程序設(shè)計(jì)來說不是強(qiáng)制的,但為了和Windows程序設(shè)計(jì)風(fēng)格一致,WindowsSockets推薦使用它們。
WindowsSockets提供的Windows專用增設(shè)函數(shù)在表12.3中列出。表12.3WindowsSockets1.1版本提供的Windows專用增設(shè)函數(shù)這些函數(shù)可以按功能分為如下幾類:
(1)啟動(dòng)與中止函數(shù)。此類函數(shù)包括WSAStartup()和WSACleanup(),它們是WindowsSockets網(wǎng)絡(luò)程序必須使用的函數(shù)。
(2)異步服務(wù)函數(shù)。此類函數(shù)包括WSAAsyncGetXByY()類的6個(gè)函數(shù)和WSACancelAsyncRequest()。WSAAsyncGetXByY()請(qǐng)求異步服務(wù),WSACancelAsyncRequest()取消一個(gè)未完成的異步操作。
(3)異步選擇函數(shù)。?異步選擇函數(shù)WSAAsyncSelect()允許應(yīng)用程序注冊(cè)一個(gè)或幾個(gè)感興趣的網(wǎng)絡(luò)事件。
(4)阻塞處理函數(shù)。此類函數(shù)包括WSAIsBlocking()、WSACancelBlockingCall()、WSASetBlockingHook()和WSAUnhookBlockingHook()。WSAIsBlocking()函數(shù)用來檢測阻塞調(diào)用是否正在進(jìn)行,而WSACancelBlockingCall()取消一個(gè)正在進(jìn)行的阻塞調(diào)用。它們經(jīng)常是聯(lián)合起來使用的,參看下面的程序段:
if(WSAIsBlocking())WSACancelBlockingCall();
函數(shù)WSASetBlockingHook()為應(yīng)用程序設(shè)置自己的阻塞處理例程,WindowsSockets推薦下面的編程風(fēng)格:在安裝自己的阻塞處理例程時(shí),保存先前安裝的阻塞處理例程的程序?qū)嵗羔槪⒃谔幚斫Y(jié)束后恢復(fù),這樣的程序段在執(zhí)行之后不會(huì)影響原來環(huán)境中的阻塞處理例程。函數(shù)WSAUnhookBlockingHook()恢復(fù)默認(rèn)的阻塞處理例程。在多線程版本W(wǎng)indows中,沒有默認(rèn)的阻塞處理例程,調(diào)用此函數(shù)將關(guān)閉應(yīng)用程序所有的阻塞處理例程,并使任何阻塞調(diào)用產(chǎn)生阻塞該調(diào)用的線程。
(5)錯(cuò)誤處理函數(shù)。此類函數(shù)包括WSAGetLastError()和WSASetLastError()。上面介紹的WindowsSocketsAPI函數(shù)是WindowsSockets1.1版本規(guī)范定義的函數(shù)標(biāo)準(zhǔn)集,任何WindowsSockets實(shí)現(xiàn)都支持這些函數(shù)。另外,特定的WindowsSockets實(shí)現(xiàn)可能提供了更為豐富的功能。在WindowsSockets規(guī)范中規(guī)定,從WindowsSocketsDLL引出的附加接口的序數(shù)必須在1000以上,1000以內(nèi)的序數(shù)保留給將來的WindowsSockets使用。那些使用了特定的WindowsSockets實(shí)現(xiàn)所提供的附加接口的應(yīng)用程序,可能不會(huì)在其他軟件商提供的WindowsSockets上正常工作。建議在設(shè)計(jì)應(yīng)用程序時(shí),不要靜態(tài)地把DLL連接到應(yīng)用程序,而要使用Windows例程LoadLibary()和ProcAddress()動(dòng)態(tài)連接,這樣在不支持應(yīng)用程序所使用的某些API函數(shù)時(shí)能夠給出一個(gè)出錯(cuò)消息。12.3.2標(biāo)準(zhǔn)Sockets函數(shù)
1.?accept()
accept()用于面向連接服務(wù)器。參數(shù)addr和addrlen存放客戶方的地址信息。調(diào)用前addr指向一個(gè)初始值為空的地址結(jié)構(gòu),而addrlen的初始值為0;調(diào)用accept()后,服務(wù)器等待從編號(hào)為s的套接字上接受客戶連接請(qǐng)求,連接請(qǐng)求是客戶方的connect()調(diào)用發(fā)出的。當(dāng)有連接請(qǐng)求到達(dá)時(shí),accept()調(diào)用將請(qǐng)求連接隊(duì)列上的第一個(gè)客戶方套接字地址及長度放入addr和addrlen,并創(chuàng)建一個(gè)與s有相同特性的新套接字號(hào)。新套接字號(hào)可用于處理服務(wù)器并發(fā)請(qǐng)求。
2.?bind()
此函數(shù)用于未連接的數(shù)據(jù)報(bào)或流套接字,將一個(gè)本地地址與套接字相連接,即建立半相關(guān)。當(dāng)用socket()創(chuàng)建一個(gè)套接字后,它存在于一名字空間(地址族),但沒有賦予名字。bind()通過將一本地名字賦予一未命名的套接字,建立起套接字的本地連接(主機(jī)地址/端口號(hào))。
3.?closesocket()
closesocket()關(guān)閉套接字s,并釋放分配給該套接字的資源。如果s涉及一個(gè)打開的TCP連接,則該連接被釋放。
語法:
intWSAAPIclosesocket(SOCKETs);
參數(shù):
s是待關(guān)閉的套接字的描述符。
返回值:
如果沒有錯(cuò)誤產(chǎn)生,closesocket()返回0,否則;返回SOCKET_ERROR。
4.?connect()
此函數(shù)用于與對(duì)等方建立一個(gè)連接。如果套接字s沒有綁定,則系統(tǒng)賦予本地相關(guān)的惟一值,并且將套接字表示為已綁定的。
語法:
intWSAAPIconnect(SOCKETs,conststructsockaddrFAR*name,intnamelen);
參數(shù):
s是欲建立的本地套接字的描述符(套接字號(hào))。
name指出對(duì)方套接字地址結(jié)構(gòu)的指針。
namelen是name指向的socketaddress結(jié)構(gòu)的字節(jié)數(shù)。返回值:
如果沒有錯(cuò)誤產(chǎn)生,connect()返回0;否則,返回SOCKET_ERROR。
5.?getpeername()
此函數(shù)用于獲取與套接字連接的對(duì)等方的地址,它檢索與套接字s連接的對(duì)等方的名字,并存在sockaddr結(jié)構(gòu)的name域中。此函數(shù)只能用于已連接的數(shù)據(jù)報(bào)或流套接字。對(duì)于數(shù)據(jù)報(bào)套接字,只有在先前的connect()調(diào)用中指定的對(duì)等方的名字被返回,而不會(huì)返回先前的sendto()調(diào)用指定的名字。語法:
intWSAAPIgetpeername(SOCKETs,structsockaddrFAR*name,intFAR*namelen);
參數(shù):
s是標(biāo)識(shí)已連接的套接字的描述符。
name是指向連接的套接字網(wǎng)際地址的指針,該結(jié)構(gòu)由getpeername()在返回前填寫,name的格式由通信發(fā)生的區(qū)域決定。
namelen是指向name所指向的結(jié)構(gòu)的大小的指針,返回時(shí)含有名字的實(shí)際字節(jié)數(shù)。
返回值:
如果沒有錯(cuò)誤產(chǎn)生,getpeername()返回0;否則,返回SOCKET_ERROR。
6.?getsockname()
此函數(shù)用于獲取套接字的本地名。它檢索指定套接字描述符的當(dāng)前名字,并存放于sockaddr結(jié)構(gòu)的name域中。它用參數(shù)s指定一個(gè)已綁定或已連接的套接字,返回與該套接字相連的本地地址。當(dāng)調(diào)用connect()函數(shù)之前沒有調(diào)用bind()函數(shù)時(shí),該調(diào)用特別有用,它提供了惟一一種用來確定系統(tǒng)設(shè)置的本地連接的方法。
語法:
intWSAAPIgetsockname(SOCKETs,structsockaddrFAR*name,intFAR*namelen);參數(shù):
s是已綁定(bind())的套接字的描述符。
name是接收套接字的地址(名字)的緩沖區(qū)指針。
namelen是指向name緩沖區(qū)大小的指針,返回名字的實(shí)際字節(jié)數(shù)。
返回值:
如果沒有錯(cuò)誤產(chǎn)生,getsockname()返回0;否則,返回SOCKET_ERROR。
7.?getsockopt()
此函數(shù)用來獲取套接字選項(xiàng)。它檢索與任何類型、任何狀態(tài)的套接字相連的套接字選項(xiàng)的當(dāng)前值,并把結(jié)果存入optval。選項(xiàng)可能在多個(gè)協(xié)議層存在,但它們總是表現(xiàn)在最高的“socket”層。選項(xiàng)影響套接字操作,如一個(gè)操作是否阻塞、包的路由選擇、帶外數(shù)據(jù)傳輸?shù)取?/p>
語法:
intWSAAPIgetsockopt(SOCKETs,intlevel,intoptname,charFAR*optval,intFAR*optlen);參數(shù):
s為套接字描述符。
level為設(shè)置選項(xiàng)的層,只支持SOL_SOCKET和IPPROTO_TCP。
optname是指定要檢索的套接字選項(xiàng)的名字。
optval是指向查詢選項(xiàng)返回值的緩沖區(qū)的指針。
optlen是指向optval緩沖區(qū)大小的指針。
返回值:
如果沒有錯(cuò)誤產(chǎn)生,getsockopt()返回0;否則,返回SOCKET_ERROR。
8.?htonl()
此函數(shù)將一個(gè)u_long類型數(shù)(32位無符號(hào)整數(shù))從主機(jī)字節(jié)順序轉(zhuǎn)換成TCP/IP網(wǎng)絡(luò)字節(jié)順序。
語法:
u_longWSAAPIhtonl(u_longhostlong);
參數(shù):
hostlong是指主機(jī)字節(jié)順序表示的32位無符號(hào)整數(shù)。
返回值:
返回一個(gè)TCP/IP網(wǎng)絡(luò)字節(jié)順序表示的32位值。
9.?htons()
此函數(shù)將一個(gè)u_short類型數(shù)(16位無符號(hào)整數(shù))從主機(jī)字節(jié)順序轉(zhuǎn)換成TCP/IP網(wǎng)絡(luò)字節(jié)順序。
語法:
u_shortWSAAPIhtons(u_shorthostshort);
參數(shù):
hostshort是按主機(jī)字節(jié)順序表示的16位無符號(hào)整數(shù)。
返回值:
返回一個(gè)TCP/IP網(wǎng)絡(luò)字節(jié)順序表示的16位值。
10.?inet_addr()
此函數(shù)將一個(gè)用點(diǎn)分表示法表示地址的字符串地址轉(zhuǎn)換成網(wǎng)際地址in_addr形式。所有網(wǎng)際地址都以網(wǎng)絡(luò)字節(jié)順序(字節(jié)順序從左到右)返回。
語法:
unsignedlongWSAAPIinet_addr(constcharFAR*cp);
參數(shù):
cp是含有用網(wǎng)際標(biāo)準(zhǔn)點(diǎn)分表示法表示地址的字符串。
返回值:
如果沒有錯(cuò)誤產(chǎn)生,inet_addr()返回一個(gè)無符號(hào)長整數(shù),用適合網(wǎng)際地址的二進(jìn)制表示;否則,返回INADDR_NONE。
11.?inet_ntoa()
此函數(shù)將一個(gè)網(wǎng)際地址轉(zhuǎn)換成點(diǎn)分十進(jìn)制表示法表示的字符串。它接收由參數(shù)in指定的網(wǎng)際地址結(jié)構(gòu),返回以點(diǎn)分表示法表示的地址的ASCII字符串。
語法:
charFAR*WSAAPIinet_ntoa(structin_addrin);
參數(shù):
in表示主機(jī)網(wǎng)際地址結(jié)構(gòu)。
返回值:
如果沒有錯(cuò)誤產(chǎn)生,inet_ntoa()返回一個(gè)字符指針,該指針含有以點(diǎn)分十進(jìn)制表示法表示的正文地址靜態(tài)緩沖區(qū),否則,返回NULL。
12.?ioctlsocket()
此函數(shù)控制套接字模式,它用于處在任何狀態(tài)的任何套接字,用來獲取或檢索與套接字相關(guān)的、獨(dú)立于協(xié)議和通信子系統(tǒng)的操作參數(shù)。
語法:
intWSAAPIioctlsocket(SOCKETs,longcmd,u_longFAR*argp);
參數(shù):
s是套接字的描述符。
cmd是在套接字s上執(zhí)行的命令。
argp是指向cmd命令的參數(shù)的指針。返回值:
成功結(jié)束則ioctlsocket()返回0;否則,返回SOCKET_ERROR。
13.?listen()
此函數(shù)只用于流套接字,執(zhí)行兩個(gè)操作:若沒有為s調(diào)用過bind(),則listen()完成套接字s所必需的連接;建立長度為backlog的請(qǐng)求連接隊(duì)列來存放即將到來的連接請(qǐng)求。
語法:
intWSAAPIlisten(SOCKETs,intbacklog);參數(shù):
s標(biāo)識(shí)一個(gè)本地已建立、尚未連接的套接字號(hào),服務(wù)器愿意從它上面接收請(qǐng)求。
backlog表示請(qǐng)求連接隊(duì)列的最大長度,用于限制排隊(duì)請(qǐng)求的個(gè)數(shù),目前允許的最大值為5。
返回值:
如果沒有錯(cuò)誤產(chǎn)生,listen()返回0;否則,返回SOCKET_ERROR。
14.?ntohl()
此函數(shù)將一個(gè)u_long類型數(shù)(32位無符號(hào)整數(shù))從TCP/IP網(wǎng)絡(luò)字節(jié)順序轉(zhuǎn)換成主機(jī)字節(jié)順序。
語法:
u_longWSAAPIntohl(u_longnetlong);
參數(shù):
netlong是TCP/IP網(wǎng)絡(luò)字節(jié)順序表示的32位無符號(hào)整數(shù)。
返回值:
返回一個(gè)主機(jī)字節(jié)順序表示的32位值。
15.?ntohs()
此函數(shù)將一個(gè)u_short類型數(shù)(16位無符號(hào)整數(shù))從TCP/IP網(wǎng)絡(luò)字節(jié)順序轉(zhuǎn)換成主機(jī)字節(jié)順序。
語法:
u_shortWSAAPIntohs(u_shortnetshort);
參數(shù):
netshort是TCP/IP網(wǎng)絡(luò)字節(jié)順序表示的16位無符號(hào)整數(shù)。
返回值:
返回一個(gè)主機(jī)字節(jié)順序表示的16位值。
16.?recv()
此函數(shù)用于在參數(shù)s指定的已連接的數(shù)據(jù)報(bào)或流套接字上讀取輸入數(shù)據(jù)。
語法:
intWSAAPIrecv(SOCKETs,charFAR*buf,intlen,intflags);
參數(shù):
s為已連接的套接字描述符。
buf是指向接收輸入數(shù)據(jù)緩沖區(qū)的指針。
len為buf所指向的緩沖區(qū)的長度。
flags為指定調(diào)用方式,可用來與套接字相關(guān)的選項(xiàng)一起影響函數(shù)的功能。返回值:
如果沒有錯(cuò)誤產(chǎn)生,recv()返回總共接收的字節(jié)數(shù);如果連接被關(guān)閉,返回0,否則,返回SOCKET_ERROR。
17.?recvfrom()
此函數(shù)用于在參數(shù)s指定的套接字(可能已連接)上讀取輸入數(shù)據(jù),并捕獲發(fā)送數(shù)據(jù)的地址,存入源地址緩沖區(qū)。
語法:
intWSAAPIrecvfrom(SOCKETs,charFAR*buf,intlen,intflags,structsockaddrFAR*from,intFAR*fromlen);參數(shù):
s為已連接的套接字的描述符。
buf是指向接收輸入數(shù)據(jù)緩沖區(qū)的指針。
len為buf所指向的緩沖區(qū)的長度。
flags是指定調(diào)用方式,可用來與套接字相關(guān)的選項(xiàng)一起影響函數(shù)的功能。
from是任選指針,指示源地址緩沖區(qū)。
fromlen是任選指針,指示源地址緩沖區(qū)的長度。
返回值:
如果沒有錯(cuò)誤產(chǎn)生,recvfrom()返回收到的字節(jié)數(shù);如果連接被關(guān)閉,返回0,否則,返回SOCKET_ERROR。
18.?select()
此函數(shù)用來檢測一個(gè)或多個(gè)套接字的狀態(tài)。對(duì)每個(gè)套接字來說,這個(gè)調(diào)用可以請(qǐng)求讀、寫或錯(cuò)誤狀態(tài)的信息。請(qǐng)求給定狀態(tài)的套接字集合由一個(gè)fd_set結(jié)構(gòu)指示。在返回時(shí),此結(jié)構(gòu)被更新,以反映那些特定條件的套接字的子集,同時(shí),select()返回滿足條件的套接字的數(shù)目。
語法:
intWSAAPIselect(intnfds,fd_setFAR*readfds,fd_setFAR*writefds,fd_setFAR*exceptfds,conststructtimevalFAR*timeout);參數(shù):
nfds指明被檢查的套接字描述符的值域,一般忽略該參數(shù)。
readfds是指向要做讀檢測的套接字描述符集合的指針。
writefds是指向要做寫檢測的套接字描述符集合的指針。
exceptfds是指向要檢測是否出錯(cuò)的套接字描述符集合的指針。
timeout是指向select()等待的最大時(shí)間。如設(shè)為NULL,則為阻塞操作。返回值:
如果沒有錯(cuò)誤產(chǎn)生,select()返回包含在fd_set結(jié)構(gòu)中已準(zhǔn)備好的套接字描述符的總數(shù)目;否則,返回SOCKET_ERROR。
19.?send()
此函數(shù)用于在參數(shù)s指定的已連接的數(shù)據(jù)報(bào)或流套接字上發(fā)送輸出數(shù)據(jù)。
語法:
intWSAAPIsend(SOCKETs,constcharFAR*buf,intlen,intflags);參數(shù):
s為已建立的本地套接字的描述符。
buf是指向存有發(fā)送數(shù)據(jù)的緩沖區(qū)的指針。
len是buf指向緩沖區(qū)中數(shù)據(jù)的長度。
flags是指定調(diào)用方式,可用來與套接字相關(guān)的選項(xiàng)一起影響函數(shù)的功能。
返回值:
如果沒有錯(cuò)誤產(chǎn)生,send()返回總共發(fā)送的字節(jié)數(shù);否則,返回SOCKET_ERROR。
20.?sendto()
此函數(shù)用于在參數(shù)s指定的數(shù)據(jù)報(bào)或流套接字上向指定的目的地址發(fā)送輸出數(shù)據(jù)。
語法:
intWSAAPIsendto(SOCKETs,constcharFAR*buf,intlen,intflags,conststructsockaddrFAR*to,intFAR*tolen);
參數(shù):
s為已建立的本地套接字的描述符。
buf是指向存有發(fā)送數(shù)據(jù)的緩沖區(qū)的指針。
len是buf指向緩沖區(qū)中數(shù)據(jù)的長度。
flags是指定調(diào)用方式,可用來與套接字相關(guān)的選項(xiàng)一起影響函數(shù)的功能。
to是指向目的套接字地址的任選指針。
tolen是to所指向地址的長度。
返回值:
如果沒有錯(cuò)誤產(chǎn)生,send()返回總共發(fā)送的字節(jié)數(shù);否則,返回SOCKET_ERROR。
21.?setsockopt()
此函數(shù)為套接字相關(guān)的選項(xiàng)設(shè)置當(dāng)前值,套接字可以是任何類型,可以處于任何狀態(tài)。盡管選項(xiàng)可存在于多個(gè)協(xié)議層,但它們總是表現(xiàn)在最高的“socket”層。選項(xiàng)影響套接字操作,如加急數(shù)據(jù)是否在正常數(shù)據(jù)流中接收、廣播消息是否在套接字上發(fā)送等。
語法:
intWSAAPIsetsockopt(SOCKETs,intlevel,intoptname,constcharFAR*optval,intFAR*optlen);參數(shù):
s為套接字描述符。
level為選項(xiàng)定義的層次,只支持SOL_SOCKET和IPPROTO_TCP。
optname是指定套接字選項(xiàng)的名字。
optval是指向請(qǐng)求選項(xiàng)數(shù)據(jù)緩沖區(qū)的指針。
optlen是選項(xiàng)數(shù)據(jù)optval緩沖區(qū)的長度。
返回值:
如果沒有錯(cuò)誤產(chǎn)生,setsockopt()返回0;否則,返回SOCKET_ERROR。
22.?shutdown()
此函數(shù)用來切斷一個(gè)雙向連接的接收、發(fā)送部分或全部連接。
語法:
intWSAAPIshutdown(SOCKETs,inthow);
參數(shù):
s是套接字描述符。
how是斷路方式,有0,1,2三種不同情況,分別是:如how為0(SD_RECEIVE),套接字上后續(xù)的接收將被禁止,這對(duì)低層的協(xié)議沒有影響;如how為1(SD_SEND),后續(xù)的發(fā)送數(shù)據(jù)被禁止;如how為2(SD_BOTH),將同時(shí)禁止后繼數(shù)據(jù)的發(fā)送和接收。返回值:
如果沒有錯(cuò)誤產(chǎn)生,shutdown()返回0;否則,返回SOCKET_ERROR。
23.?socket()
此函數(shù)建立一個(gè)套接字,它給指定的地址族、數(shù)據(jù)類型和協(xié)議分配一個(gè)套接字描述符以及相關(guān)的資源。根據(jù)這三個(gè)參數(shù)建立一個(gè)套接字,并將相應(yīng)的資源分配給它,同時(shí)返回一個(gè)整型套接字號(hào)。因此socket()系統(tǒng)調(diào)用實(shí)際上指定了相關(guān)五元組中的“協(xié)議”這一元。
語法:
SOCKETWSAAPIsocket(intaf,inttype,intprotocol);參數(shù):
af是一種地址格式描述?,F(xiàn)在支持的格式只有PF_INET,為ARPA網(wǎng)際地址格式。
type描述要建立的套接字的類型。
protocol說明該套接字使用的特定協(xié)議,如果調(diào)用者不希望特別指定使用的協(xié)議,則置為0,使用默認(rèn)的連接模式。
返回值:
如果沒有錯(cuò)誤產(chǎn)生,socket()返回一個(gè)與建立的套接字相關(guān)的描述符;否則,返回INVALID_SOCKET。12.3.3數(shù)據(jù)庫函數(shù)
1.?gethostbyaddr()
此函數(shù)用來通過地址獲取主機(jī)信息。對(duì)于數(shù)據(jù)庫函數(shù)中的getXbyY()類型的函數(shù)來說,它們返回的指針指向的結(jié)構(gòu)是由WindowsSockets實(shí)現(xiàn)分配的。應(yīng)用程序不能修改此結(jié)構(gòu)或釋放它的任一部件。
語法:
structhostentFAR*WSAAPIgethostbyaddr(constcharFAR*addr,intlen,inttype);參數(shù):
addr是指向一個(gè)網(wǎng)絡(luò)字節(jié)順序表示的32位網(wǎng)際地址的指針。
len表示addr的字節(jié)數(shù),對(duì)PF_INET地址,必須為4。
type是地址類型,必須為PF_INET。
返回值:
如果沒有錯(cuò)誤產(chǎn)生,gethostbyaddr()返回一個(gè)hostent結(jié)構(gòu)指針;否則,返回NULL指針。
2.?gethostbyname()
此函數(shù)用來通過主機(jī)名獲取主機(jī)信息,它返回hostent結(jié)構(gòu)的指針,此結(jié)構(gòu)包含與給定的主機(jī)名相對(duì)應(yīng)的名字和地址。gethostbyname()函數(shù)不能理解傳遞給它的IP地址字符串,這個(gè)請(qǐng)求只能當(dāng)作傳送了一個(gè)未知的主機(jī)名來處理。要分析IP地址字符串,應(yīng)該使用inet_addr()來將字符串轉(zhuǎn)換成IP地址,然后調(diào)用gethostbyaddr()來獲得hostent結(jié)構(gòu)。
語法:
structhostentFAR*WSAAPIgethostbyname(constcharFAR*name);參數(shù):
name為所查詢主機(jī)的名字。
返回值:
如果沒有錯(cuò)誤產(chǎn)生,gethostbyname()返回一個(gè)hostent結(jié)構(gòu)的指針;否則,返回NULL指針。
3.?gethostname()
此函數(shù)在參數(shù)指定的緩沖區(qū)中返回本地主機(jī)的名字,是一個(gè)以NULL結(jié)束的字符串。
語法:
intWSAAPIgethostname(charFAR*name,intnamelen);
參數(shù):
name是指向接受主機(jī)名的緩沖區(qū)的指針。
namelen是緩沖區(qū)的長度。
返回值:
如果沒有錯(cuò)誤產(chǎn)生,gethostname()返回0;否則,返回SOCKET_ERROR。
4.?getprotobyname()
此函數(shù)用來獲取協(xié)議信息。
語法:
structprotoentFAR*WSAAPIgetprotobyname(constcharFAR*name);
參數(shù):
name是指向協(xié)議名的指針。
返回值:
如果沒有錯(cuò)誤產(chǎn)生,getprotobyname()返回一個(gè)protoent結(jié)構(gòu)指針;否則,返回NULL指針。
5.?getprotobynumber()
此函數(shù)通過協(xié)議號(hào)獲取協(xié)議信息,返回protoent結(jié)構(gòu)指針,此結(jié)構(gòu)包含與給定的協(xié)議號(hào)相對(duì)應(yīng)的名字和協(xié)議號(hào)。
語法:
structprotoentFAR*WSAAPIgetprotobynumber(intnumber);
參數(shù):
number是用主機(jī)字節(jié)順序表示的協(xié)議號(hào)。
返回值:
如果沒有錯(cuò)誤產(chǎn)生,getprotobynumber()返回一個(gè)protoent結(jié)構(gòu)指針;否則,返回NULL指針。
6.?getservbyname()
此函數(shù)用來獲取服務(wù)信息,返回servent結(jié)構(gòu)指針,此結(jié)構(gòu)內(nèi)容通過給定服務(wù)名name和協(xié)議名proto獲得,包含服務(wù)名和服務(wù)端口號(hào)。
語法:
structserventFAR*WSAAPIgetservbyname(constcharFAR*name,constcharFAR*proto);參數(shù):
name是指向服務(wù)名的指針。
proto是指向協(xié)議名的指針,該參數(shù)可選。如為NULL,getservbyname()返回服務(wù)名s_name或服務(wù)別名s_aliases之中與name匹配的第一個(gè)服務(wù)入口,否則,getservbyname()同時(shí)匹配服務(wù)名name和協(xié)議名proto。
返回值:
如果沒有錯(cuò)誤產(chǎn)生,getservbyname()返回一個(gè)servent結(jié)構(gòu)的指針;否則,返回NULL指針。
7.?getservbyport()
此函數(shù)用來獲取服務(wù)信息,返回servent結(jié)構(gòu)的指針,此結(jié)構(gòu)的內(nèi)容通過給定端口號(hào)port和協(xié)議名proto獲得,包含服務(wù)名和服務(wù)端口號(hào)。
語法:
structserventFAR*WSAAPIgetservbyport(intport,constcharFAR*proto);參數(shù):
port是服務(wù)使用的端口號(hào),用網(wǎng)絡(luò)字節(jié)順序表示。
proto是指向協(xié)議名的指針,該參數(shù)可選。如為NULL,getservbyport()返回服務(wù)端口號(hào)s_port與port匹配的第一個(gè)服務(wù)入口,否則,getservbyport()同時(shí)匹配服務(wù)端口號(hào)port和協(xié)議名proto。
返回值:
如果沒有錯(cuò)誤產(chǎn)生,getservbyport()返回一個(gè)servent結(jié)構(gòu)指針;否則,返回NULL指針。12.3.4增設(shè)函數(shù)
1.?WSAAsyncGetHostByAddr()
此函數(shù)是gethostbyaddr()的異步版本,用來通過網(wǎng)絡(luò)地址獲取主機(jī)的名字和地址信息。
語法:
HANDLEWSAAPIWSAAsyncGetHostByAddr(HWNDhWnd,unsignedintwMsg,constcharFAR*addr,intlen,inttype,charFAR*buf,intbuflen);參數(shù):
hWnd為異步請(qǐng)求完成時(shí),接收消息的窗口句柄。
wMsg為異步請(qǐng)求完成時(shí),接收到的消息。
addr為指向主機(jī)網(wǎng)絡(luò)地址的指針,主機(jī)網(wǎng)絡(luò)地址用網(wǎng)絡(luò)字節(jié)順序存儲(chǔ)。
len為地址長度,對(duì)PF_INET族,必須為4。
type為地址類型,必須為PF_INET。
buf為接收主機(jī)信息的數(shù)據(jù)緩沖區(qū)的指針,它的長度必須大于hostent結(jié)構(gòu)的長度。
buflen為buf指向緩沖區(qū)的長度。
返回值:
如果操作被成功初始化,返回一個(gè)HANDLE類型的非零值,它是此請(qǐng)求的異步任務(wù)句柄;否則,返回0。
2.?WSAAsyncGetHostByName()
此函數(shù)是gethostbyname()的異步版本,用來通過主機(jī)名字獲取主機(jī)的名字和地址信息。
語法:
HANDLEWSAAPIWSAAsyncGetHostByName(HWNDhWnd,unsignedintwMsg,constcharFAR*name,charFAR*buf,intbuflen);
參數(shù):
hWnd為異步請(qǐng)求完成時(shí),接收消息的窗口的句柄。
wMsg為異步請(qǐng)求完成時(shí),接收到的消息。
name是指向主機(jī)名字的指針。
buf是接收主機(jī)信息的數(shù)據(jù)緩沖區(qū)的指針,它的長度必須大于hostent結(jié)構(gòu)的長度。
buflen是buf指向緩沖區(qū)的長度。
返回值:
如果操作被成功初始化,返回一個(gè)HANDLE類型的非零值,它是此請(qǐng)求的異步任務(wù)句柄;否則,返回0。
3.?WSAAsyncGetProtoByName()
此函數(shù)是getprotobyname()的異步版本,用來通過協(xié)議名獲取協(xié)議的名字和協(xié)議號(hào)信息。
語法:
HANDLEWSAAPIWSAAsyncGetProtoByName(HWNDhWnd,unsignedintwMsg,constcharFAR*name,charFAR*buf,intbuflen);參數(shù):
hWnd為異步請(qǐng)求完成時(shí),接收消息的窗口的句柄。
wMsg為異步請(qǐng)求完成時(shí),接收到的消息。
name是指向要查詢的協(xié)議名字的指針。
buf是接收協(xié)議信息的數(shù)據(jù)緩沖區(qū)的指針,它的長度必須大于protoent結(jié)構(gòu)的長度。
buflen是buf指向緩沖區(qū)的長度。
返回值:
如果操作被成功初始化,返回一個(gè)HANDLE類型的非零值,它是此請(qǐng)求的異步任務(wù)句柄;否則,返回0。
4.?WSAAsyncGetProtoByNumber()
此函數(shù)是getprotobynumber()的異步版本,用來通過協(xié)議號(hào)獲取協(xié)議的名字和協(xié)議號(hào)信息。
語法:
HANDLEWSAAPIWSAAsyncGetProtoByNumber(HWNDhWnd,unsignedintwMsg,intnumber,charFAR*buf,intbuflen);參數(shù):
hWnd為異步請(qǐng)求完成時(shí),接收消息的窗口的句柄。
wMsg為異步請(qǐng)求完成時(shí),接收到的消息。
name是指向要查詢的協(xié)議名字的指針,用主機(jī)字節(jié)順序表示。
buf為接收協(xié)議信息的數(shù)據(jù)緩沖區(qū)的指針,它的長度必須大于protoent結(jié)構(gòu)的長度。
buflen為buf指向緩沖區(qū)的長度。
返回值:
如果操作被成功初始化,返回一個(gè)HANDLE類型的非零值,它是此請(qǐng)求的異步任務(wù)句柄;否則,返回0。
5.?WSAAsyncGetServByName()
此函數(shù)是getservbyname()的異步版本,用來通過服務(wù)名字和協(xié)議名獲取服務(wù)信息。
語法:
HANDLEWSAAPIWSAAsyncGetServByName(HWNDhWnd,unsignedintwMsg,constcharFAR*name,constcharFAR*proto,charFAR*buf,intbuflen);
參數(shù):
hWnd為異步請(qǐng)求完成時(shí),接收消息的窗口的句柄。
wMsg為異步請(qǐng)求完成時(shí),接收到的消息。
name是指向服務(wù)名字的指針。
proto是指向協(xié)議名的指針,如為NULL,函數(shù)尋找服務(wù)名s_name或服務(wù)別名s_aliases之一與給定的name相匹配的第一個(gè)服務(wù)入口;否則,函數(shù)同時(shí)匹配服務(wù)名
name和協(xié)議名proto。
buf為接收主機(jī)信息的數(shù)據(jù)緩沖區(qū)的指針,它的長度必須大于servent結(jié)構(gòu)的長度。
buflen為buf指向緩沖區(qū)的長度。
返回值:
如果操作被成功初始化,返回一個(gè)HANDLE類型的非零值,它是此請(qǐng)求的異步任務(wù)句柄;否則,返回0。
6.?WSAAsyncGetServByPort()
此函數(shù)是getservbyport()的異步版本,用來通過端口號(hào)和協(xié)議名獲取服務(wù)信息。
語法:
HANDLEWSAAPIWSAAsyncGetServByPort(HWNDhWnd,unsignedintwMsg,intport,constcharFAR*proto,charFAR*buf,intbuflen);
參數(shù):
hWnd為異步請(qǐng)求完成時(shí),接收消息的窗口的句柄。
wMsg為異步請(qǐng)求完成時(shí),接收到的消息。
port為服務(wù)端口號(hào),用網(wǎng)絡(luò)字節(jié)順序表示。
proto是指向協(xié)議名的指針,如為NULL,函數(shù)尋找服務(wù)端口號(hào)s_port與給定的端口port相匹配的第一個(gè)服務(wù)入口;否則,函數(shù)同時(shí)匹配port和proto。
buf為接收主機(jī)信息的數(shù)據(jù)緩沖區(qū)的指針,它的長度必須大于servent結(jié)構(gòu)的長度。
buflen為buf指向緩沖區(qū)的長度。
返回值:
如果操作被成功初始化,返回一個(gè)HANDLE類型的非零值,它是此請(qǐng)求的異步任務(wù)句柄;否則,返回0。
7.?WSAAsyncSelect()
此函數(shù)為套接字請(qǐng)求基于Windows消息的事件通知,用于請(qǐng)求WindowsSocketsDLL在檢測到由參數(shù)lEvent指定的網(wǎng)絡(luò)事件時(shí),向窗口hWnd發(fā)送一個(gè)消息。發(fā)送的消息由參數(shù)wMsg指定,要求接到通知的套接字由參數(shù)s標(biāo)識(shí)。此函數(shù)自動(dòng)地設(shè)置套接字s處于非阻塞方式。
語法:
intWSAAPIWSAAsyncSelect(SOCKETs,HWNDhWnd,unsignedintwMsg,longlEvent);參數(shù):
s是標(biāo)識(shí)請(qǐng)求事件通知的套接字的描述符。
hWnd是標(biāo)識(shí)網(wǎng)絡(luò)事件發(fā)生時(shí),接收消息的窗口的句柄。
wMsg為網(wǎng)絡(luò)事件發(fā)生時(shí),窗口接收到的消息。
lEvent為指定應(yīng)用程序感興趣的網(wǎng)絡(luò)事件組合的位屏蔽。
返回值:
如果應(yīng)用程序?qū)Ω信d趣的網(wǎng)絡(luò)事件集的注冊(cè)登記成功,返回0;否則,返回SOCKET_ERROR。
8.?WSACancelAsyncRequest()
此函數(shù)用來取消由WSAAsyncGetXByY()類函數(shù)引起的異步操作。被取消的操作由參數(shù)hAsyncTaskHandle標(biāo)識(shí),此參數(shù)由原始調(diào)用函數(shù)返回,是此異步任務(wù)的句柄。
語法:
intWSAAPIWSACancelAsyncRequest(HANDLEhAsyncTaskHandle);
參數(shù):
hAsyncTaskHandle是指示將被取消的異步操作的異步任務(wù)句柄。
返回值:
如果操作被成功取消,返回0;否則,返回SOCKET_ERROR。
9.?WSACancelBlockingCall()
此函數(shù)為當(dāng)前任務(wù)取消任何尚未完成的阻塞調(diào)用。
語法:
intWSAAPIWSACancelBlockingCall(void);
參數(shù):
無。
返回值:
如果操作被成功取消,返回0;否則,返回SOCKET_ERROR。
10.?WSACleanup()
此函數(shù)用來結(jié)束對(duì)WindowsSocketsDLL的使用。
語法:
intWSAAPIWSACleanup(void);
參數(shù):
無。
返回值:
如果操作成功,返回0;否則,返回SOCKET_ERROR。
11.?WSAGetLastError()
此函數(shù)用來獲取最近失敗操作的錯(cuò)誤碼,返回最近產(chǎn)生的網(wǎng)絡(luò)錯(cuò)誤。
語法:
intWSAAPIWSAGetLastError(void);
參數(shù):
無。
返回值:
返回值指示當(dāng)前線程最近執(zhí)行的WindowsSocketsAPI函數(shù)產(chǎn)生的錯(cuò)誤。
12.?WSAIsBlocking()
此函數(shù)用來檢查阻塞調(diào)用是否正在進(jìn)行,允許任務(wù)在等待一個(gè)先前的阻塞調(diào)用完成時(shí),檢測此調(diào)用是否正在進(jìn)行。
語法:
BOOLWSAAPIWSAIsBlocking(void);
參數(shù):
無。
返回值:
如果當(dāng)前線程存在未完成的阻塞函數(shù),返回TRUE;否則,返回FALSE。
13.?WSASetBlockingHook()
此函數(shù)用來建立特定應(yīng)用程序的阻塞處理例程。
語法:
FARPROCWSAAPIWSASetBlockingHook(FARPROClpBlockFunc);
參數(shù):
lpBlockFunc是指向要安裝的阻塞處理例程的過程實(shí)例地址的指針。
返回值:
返回值為先前安裝的阻塞處理例程的程序?qū)嵗羔?,調(diào)用者應(yīng)該保存這個(gè)返回值以便在必要時(shí)恢復(fù);如操作失敗,返回NULL指針。
14.?WSASetLastError()
此函數(shù)允許應(yīng)用程序?yàn)楫?dāng)前線程設(shè)置錯(cuò)誤碼,此代碼可由其后的WSAGetLastError()調(diào)用獲得。
語法:
voidWSAAPIWSASetLastError(intiError);
參數(shù):
iError指示由其后的WSAGetLastError()調(diào)用返回的錯(cuò)誤碼。
返回值:
無。
15.?WSAStartup()
此函數(shù)初始化WindowsSocketsDLL,必須是應(yīng)用程序或DLL第一個(gè)調(diào)用的WindowsSockets函數(shù)。它允許應(yīng)用程序或DLL指定WindowsSocketsAPI要求的版本,以獲取指定的WindowsSockets實(shí)現(xiàn)的細(xì)節(jié)。應(yīng)用程序或DLL只有在一次成功的WSAStartup()執(zhí)行后才能發(fā)布后續(xù)的WinSock函數(shù)。
語法:
intWSAAPIWSAStartup(WORDwVersionRequested,LPWSADATAlpWSAData);參數(shù):
wVersionRequested為調(diào)用者可以使用的WindowsSocketsAPI支持的最高版本號(hào)。
lpWSAData是指向接收WindowsSockets實(shí)現(xiàn)細(xì)節(jié)的數(shù)據(jù)結(jié)構(gòu)WSADATA的指針。
返回值:
如果調(diào)用成功,返回0;否則,返回錯(cuò)誤碼。
16.?WSAUnhookBlockingHook()
此函數(shù)刪除先前安裝的任何阻塞處理例程,并重新安裝默認(rèn)的阻塞機(jī)制。在多線程版本W(wǎng)indows中,沒有默認(rèn)的阻塞處理例程,調(diào)用此函數(shù)將關(guān)閉應(yīng)用程序安裝的所有阻塞處理例程,并使任何阻塞調(diào)用產(chǎn)生阻塞該調(diào)用的線程。
語法:
intWSAAPIWSAUnhookBlockingHook(void);
參數(shù):
無。
返回值:
如果操作成功,返回0;否則,返回SOCKET_ERROR。
12.4典型套接字系統(tǒng)調(diào)用時(shí)序圖
TCP/IP協(xié)議的應(yīng)用一般采用客戶機(jī)/服務(wù)器模式。因此,在實(shí)際應(yīng)用中,必須有客戶和服務(wù)器兩個(gè)進(jìn)程,并要先啟動(dòng)服務(wù)器。面向連接協(xié)議(如TCP)的套接字系統(tǒng)調(diào)用時(shí)序圖如圖12.1所示。
服務(wù)器必須首先啟動(dòng),直到執(zhí)行完accept()調(diào)用,進(jìn)入等待狀態(tài)后,方能接收客戶請(qǐng)求。如客戶在此之前啟動(dòng),則connect()將返回出錯(cuò)代碼,連接不成功。圖12.1面向連接的協(xié)議(如TCP)的套接字系統(tǒng)調(diào)用時(shí)序圖無連接協(xié)議的套接字系統(tǒng)調(diào)用時(shí)序圖如圖12.2所示。
無連接服務(wù)器也必須先啟動(dòng),否則客戶請(qǐng)求傳不到服務(wù)進(jìn)程。無連接客戶不調(diào)用connect(),因此,在數(shù)據(jù)發(fā)送之前,客戶與服務(wù)器之間尚未建立全相關(guān),但各自通過socket()和bind()建立了半相關(guān)。發(fā)送數(shù)據(jù)時(shí),發(fā)送方除指定本地套接字號(hào)外,還需指定接收方套接字號(hào),從而在數(shù)據(jù)收發(fā)過程中動(dòng)態(tài)的建立全相關(guān)。圖12.2無連接協(xié)議的套接字系統(tǒng)調(diào)用時(shí)序圖 12.5WindowsSockets對(duì)Berkeley Sockets的擴(kuò)充
1.異步選擇機(jī)制
WindowsSockets的異步選擇函數(shù)提供了消息機(jī)制的網(wǎng)絡(luò)事件選擇。當(dāng)使用它登記的網(wǎng)絡(luò)事件發(fā)生時(shí),Windows應(yīng)用程序相應(yīng)的窗口函數(shù)將收到一個(gè)消息,消息中指示了發(fā)生的網(wǎng)絡(luò)事件以及與事件相關(guān)的一些信息。
2.異步請(qǐng)求函數(shù)
異步請(qǐng)求函數(shù)允許應(yīng)用程序用異步方式獲得請(qǐng)求的信息,且在請(qǐng)求的服務(wù)完成時(shí)給應(yīng)用程序相應(yīng)的窗口函數(shù)發(fā)送一個(gè)消息。
3.阻塞處理方法
為了實(shí)現(xiàn)當(dāng)應(yīng)用程序的套接字調(diào)用處于阻塞時(shí),能夠放棄CPU讓其他應(yīng)用程序運(yùn)行,WindowsSockets在調(diào)用處于阻塞時(shí)便進(jìn)入一個(gè)叫“HOOK”的例程。HOOK例程負(fù)責(zé)接收和分配Windows消息,這使得其他應(yīng)用程序仍然能夠接收到自己的消息并取得控制權(quán)。WindowsSockets還提供了兩個(gè)函數(shù)(WSASetBlockingHook()和WSAUnhookBlockingHook()),讓用戶設(shè)置和取消自己的阻塞處理例程,用以支持要求復(fù)雜消息處理的應(yīng)用程序(如多文檔界面)。函數(shù)WSAIsBlocking()可以檢測是否阻塞,函數(shù)WSACancelBlockingCall()可以取消一個(gè)阻塞的調(diào)用。
4.出錯(cuò)處理
WindowsSockets為了和以后多線程環(huán)境(如WindowsNT)兼容,提供了兩個(gè)出錯(cuò)處理函數(shù)WSAGetLastError()和WSASetLastError()來獲取和設(shè)置當(dāng)前線程的最近錯(cuò)誤號(hào)。
5.啟動(dòng)與中止
由于WindowsSockets的服務(wù)是以動(dòng)態(tài)連接庫WINSOCK.DLL形式實(shí)現(xiàn)的,所以必須要先調(diào)用WSAStartup()函數(shù)對(duì)WindowsSocketsDLL進(jìn)行初始化,協(xié)商版本的支持,并分配必要的資源。在應(yīng)用程序完成了對(duì)WindowsSockets的使用之后,還應(yīng)調(diào)用函數(shù)WSACleanup(),中止對(duì)WindowsSocketsDLL的使用,并釋放資源,以備下一次使用。12.6基于WinSock函數(shù)的網(wǎng)絡(luò)應(yīng)用程序開發(fā)
在介紹了WindowsSocketsAPI的基本情況后,將介紹基于WindowsSocketsAPI的網(wǎng)絡(luò)程序設(shè)計(jì)方法。在Windows環(huán)境下,有三種基本的網(wǎng)絡(luò)應(yīng)用程序設(shè)計(jì)方法,分別如下:
(1)用基本的WindowsSocketsAPI函數(shù)來進(jìn)行網(wǎng)絡(luò)應(yīng)用程序開發(fā)。
(2)用面向?qū)ο蟮拈_發(fā)語言提供的與網(wǎng)絡(luò)通信有關(guān)的類來進(jìn)行網(wǎng)絡(luò)應(yīng)用程序開發(fā)。
(3)用可視化開發(fā)工具中的網(wǎng)絡(luò)控件來進(jìn)行網(wǎng)絡(luò)應(yīng)用程序開發(fā)。這三種方法中所使用的網(wǎng)絡(luò)應(yīng)用編程接口,由低級(jí)到高級(jí),即使是高一級(jí)的編程接口(類和網(wǎng)絡(luò)控件)也是以基本的WindowsSocketsAPI為基礎(chǔ),只不過是對(duì)低級(jí)接口在不同程度上的封裝而已。
因?yàn)閃indows環(huán)境下程序設(shè)計(jì)工具的多樣性,所以有很多可視化程序開發(fā)工具和程序設(shè)計(jì)語言(如Java,C++等)。比較著名的可視化程序設(shè)計(jì)工具有:Delphi、PowerBuilder、C++Builder、Jbuilder、VisualC++、VisualBasic等。在這些可視化開發(fā)工具中,既提供了基本的套接字API函數(shù),也提供了更高一級(jí)的編程接口:網(wǎng)絡(luò)控件或網(wǎng)絡(luò)通信類。盡管不同工具中提供的有關(guān)網(wǎng)絡(luò)程序設(shè)計(jì)的類或控件的數(shù)量和名稱有所不同,但是其基本思想和原理卻是一樣的。因此,我們將以MFC為例介紹使用類來進(jìn)行網(wǎng)絡(luò)程序設(shè)計(jì),以VisualBasic為例介紹基于網(wǎng)絡(luò)控件的網(wǎng)絡(luò)程序設(shè)計(jì)。
另外,Windows環(huán)境下的程序設(shè)計(jì)語言和工具發(fā)展很快,類和控件的數(shù)量也是處于不斷變化之中。因此,需要掌握基本的方法和思想。下面我們以一個(gè)例子介紹Winsock網(wǎng)絡(luò)程序最典型的模式:客戶機(jī)/服務(wù)器工作模式(摘自DouglasE.Comer與DavidL.Stevens合著的InternetWorkingwithTCP/IPVolumeⅢ:ClientServerProgrammingandApplications)。本例說明回顯服務(wù)(ECHO)是如何實(shí)現(xiàn)的,服務(wù)器采用的是并發(fā)模式,即對(duì)每個(gè)客戶的請(qǐng)求都用一個(gè)獨(dú)立的線程來處理,這樣能極大地提高系統(tǒng)效率,減少連接隊(duì)列中連接請(qǐng)求的大小。整個(gè)程序分為兩部分:客戶程序和服務(wù)器程序。
12.6.1服務(wù)器程序
下面介紹服務(wù)器程序,內(nèi)容如下。函數(shù)passivesock是根據(jù)不同的傳輸協(xié)議、要求提供的服務(wù),以及連接隊(duì)列的大小來創(chuàng)建服務(wù)器的監(jiān)聽套接字。函數(shù)首先調(diào)用getprotobyname取得協(xié)議的信息,從而決定使用何種地址類型來創(chuàng)建套接字,調(diào)用函數(shù)getservbyname取得相關(guān)服務(wù)信息,以設(shè)置相應(yīng)的端口;其次根據(jù)得到的信息來創(chuàng)建適當(dāng)?shù)奶捉幼?;再次,調(diào)用bind函數(shù)將創(chuàng)建的套接字與本地地址關(guān)聯(lián)起來,形成連接三元組;最后調(diào)用listen監(jiān)聽創(chuàng)建的套接字,監(jiān)聽客戶端的請(qǐng)求。
函數(shù)passiveTCP將傳輸協(xié)議“tcp”傳遞給passivesock并直接調(diào)用它。函數(shù)passiveUDP與passiveTCP基本相同,傳遞“udp”給passivesock。
main函數(shù)通用passiveTCP創(chuàng)建一個(gè)監(jiān)聽套接字,然后進(jìn)入主循環(huán),處理客戶端的連接請(qǐng)求,每次收到一個(gè)連接請(qǐng)求后程序都調(diào)用_beginthread函數(shù)為之創(chuàng)建一個(gè)
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 企業(yè)文化宣傳合同范例
- 農(nóng)村裝修貸款合同范本
- 2021-2026年中國電力維護(hù)合板市場競爭策略及行業(yè)投資潛力預(yù)測報(bào)告
- 中醫(yī)私承合同范本
- 一租房合同范本個(gè)人
- 獸藥代加工合同范本
- 上海汽車租車合同范本
- 保潔補(bǔ)簽合同范本
- 2025年度酒水行業(yè)知識(shí)產(chǎn)權(quán)保護(hù)與糾紛解決合同范本
- 勞務(wù)公司之間合同范本
- FZ∕T 54007-2019 錦綸6彈力絲行業(yè)標(biāo)準(zhǔn)
- 人教部編版四年級(jí)語文下冊(cè)課內(nèi)外閱讀訓(xùn)練2《鄉(xiāng)下人家》(有答案)
- 手術(shù)室患者人文關(guān)懷
- 高中英語語法同位語從句省公開課一等獎(jiǎng)全國示范課微課金獎(jiǎng)
- 住院病人燙傷的應(yīng)急演練
- 新入職消防員考核試卷題庫(240道)
- 2024中考復(fù)習(xí)必背初中英語單詞詞匯表(蘇教譯林版)
- 文學(xué)翻譯教學(xué)大綱
- 質(zhì)量管理與產(chǎn)品質(zhì)量保障措施
- 全國自然教育中長期發(fā)展規(guī)劃
- 第四章-國防動(dòng)員
評(píng)論
0/150
提交評(píng)論