




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
1、網(wǎng)絡程序設計 第三章Windows套接字I/O模型 沈陽航空航天大學套接字模式套接字模式選擇模型(選擇模型(Select ModelSelect Model)WindowsWindows程序基本工作原理程序基本工作原理異步選擇模型(異步選擇模型(WSAAsyncSelect ModelWSAAsyncSelect Model)事件選擇模型(事件選擇模型(WSAEventSelect ModelWSAEventSelect Model)重疊模型(重疊模型(Overlapped ModelOverlapped Model)完成端口模型(完成端口模型(Completion Port ModelCom
2、pletion Port Model) 網(wǎng)絡程序設計 第三章Windows套接字I/O模型 沈陽航空航天大學1. 套接字模式套接字模式 Windows套接字在兩種模式下執(zhí)行套接字在兩種模式下執(zhí)行I/O操作:操作:阻塞和非阻塞。阻塞和非阻塞。 在阻塞模式下,在在阻塞模式下,在I/O操作完成前,執(zhí)行操操作完成前,執(zhí)行操作的作的Winsock函數(shù)(比如函數(shù)(比如send和和recv)會一)會一直等候下去,不會立即返回程序(直等候下去,不會立即返回程序(即不會將即不會將控制權(quán)交還給程序控制權(quán)交還給程序),直到該函數(shù)操作完成,),直到該函數(shù)操作完成,或出錯?;虺鲥e。 在非阻塞模式下,在非阻塞模式下, W
3、insock函數(shù)無論如何都函數(shù)無論如何都會立即返回。會立即返回。網(wǎng)絡程序設計 第三章Windows套接字I/O模型 沈陽航空航天大學1.1 阻塞模式阻塞模式 對于處在阻塞模式的套接字,我們必須多加留意,因為在一個阻塞套接字上調(diào)用任何一個Winsock API函數(shù),都會產(chǎn)生相同的后果-耗費或長或短的時間“等待”。 一個典型的例子網(wǎng)絡程序設計 第三章Windows套接字I/O模型 沈陽航空航天大學簡單的阻塞模式示例簡單的阻塞模式示例SOCKET sock;charbuff256;intdone = 0;while(!done)nBytes = recv(sock,buff,65,0);if (nB
4、ytes = SOCKET_ERROR) printf(“recv failed with error %dn”,WSAGetLastError();return;DoComputationData(buff);假如沒有數(shù)據(jù)處于假如沒有數(shù)據(jù)處于“待決待決”狀態(tài),狀態(tài),那么那么recv函數(shù)可能永遠都無法返回。函數(shù)可能永遠都無法返回。只有從系統(tǒng)的輸入緩沖區(qū)中讀回點只有從系統(tǒng)的輸入緩沖區(qū)中讀回點什么東西,才允許返回!什么東西,才允許返回!網(wǎng)絡程序設計 第三章Windows套接字I/O模型 沈陽航空航天大學1.2 非阻塞模式非阻塞模式 非阻塞模式的套接字在使用上稍顯困難,但它在功能上非阻塞模式的套接字
5、在使用上稍顯困難,但它在功能上是非常強大的。除具備阻塞套接字已有的各項優(yōu)點之外,是非常強大的。除具備阻塞套接字已有的各項優(yōu)點之外,還進行了擴充,功能更強。還進行了擴充,功能更強。 創(chuàng)建一個套接字,并將其置為非阻塞模式的程序示例:創(chuàng)建一個套接字,并將其置為非阻塞模式的程序示例:SOCKET s;u_long ul=1;intnRet;s=socket(AF_INET,SOCK_STREAM,0);nRet=ioctlsocket(s,FIONBIO,(unsigned long *)&ul);if (nRet=SOCKET_ERROR)/Failed to put the socket into
6、 nonblocking mode網(wǎng)絡程序設計 第三章Windows套接字I/O模型 沈陽航空航天大學 設置套接字工作模式設置套接字工作模式ioctlsocket() 函數(shù)形式函數(shù)形式 : int ioctlsocket ( SOCKET s, long cmd, u_long * argp );u功能說明:功能說明:套接字默認工作在阻塞模式,此函數(shù)設置套接字的工作模套接字默認工作在阻塞模式,此函數(shù)設置套接字的工作模式為非阻塞或阻塞模式。式為非阻塞或阻塞模式。u返回值:返回值:正確調(diào)用返回正確調(diào)用返回0,否則將返回,否則將返回SOCKET_ERROR SOCKET_ERROR ,應用程序,應用
7、程序可以通過可以通過 WSAGetLastError()來獲取具體錯誤的代碼。來獲取具體錯誤的代碼。 網(wǎng)絡程序設計 第三章Windows套接字I/O模型 沈陽航空航天大學u參數(shù)說明:參數(shù)說明:cmd cmd :表示對套接字表示對套接字s s的操作控制命令。的操作控制命令。argp argp :指向指向cmdcmd命令所帶指針的參數(shù)。命令所帶指針的參數(shù)。cmd命令命令(常量常量)具體含義具體含義對應的對應的argpFIONBIO 用于設置套接字用于設置套接字s為為非阻塞或阻塞模式非阻塞或阻塞模式置置argp指向非指向非0 非阻塞模式非阻塞模式置置argp指向指向0 阻塞模式阻塞模式 FIONRE
8、AD 用于確定可從套接字用于確定可從套接字s上自動讀入的數(shù)據(jù)上自動讀入的數(shù)據(jù)量量argp指向的數(shù)表示讀入的字節(jié)指向的數(shù)表示讀入的字節(jié)數(shù)數(shù)SIOCATMARK 用于確定是否所有的用于確定是否所有的帶外數(shù)據(jù)都已經(jīng)被讀帶外數(shù)據(jù)都已經(jīng)被讀入,該命令僅適用于入,該命令僅適用于流式套接字流式套接字如無帶外數(shù)據(jù)等待讀入,則該如無帶外數(shù)據(jù)等待讀入,則該操作返回真,否則返回假。真操作返回真,否則返回假。真假值存入假值存入argp指向的數(shù)指向的數(shù) SOCKET s SOCKET s :傳入?yún)?shù)。用于標識一個:傳入?yún)?shù)。用于標識一個套接字的套接字的描述符描述符。TCP TCP 首部格式首部格式 TCP首部20字節(jié)固
9、定首部目 的 端 口數(shù)據(jù)偏移檢 驗 和選 項 (長 度 可 變)源 端 口序 號緊 急 指 針窗 口確 認 號保 留FINSYNRSTPSHACKURG位 0 8 16 24 31填 充緊急位 URG 當 URG 1 時,表明緊急指針字段有效。它告訴系統(tǒng)此報文段中有緊急數(shù)據(jù),應盡快傳送(相當于高優(yōu)先級的數(shù)據(jù))。 緊急指針字段 占 16 位。緊急指針指出在本報文段中的緊急數(shù)據(jù)的最后一個字節(jié)的序號。 網(wǎng)絡程序設計 第三章Windows套接字I/O模型 沈陽航空航天大學ioctlsocketioctlsocket使用舉例使用舉例 unsigned long mode=0;ioctlsocket(so
10、ckfd,FIONBIO,&mode); unsigned long mode=1;ioctlsocket(sockfd,FIONBIO,&mode); unsigned long arg ;ioctlsocket(sockfd, FIONREAD ,&arg);網(wǎng)絡程序設計 第三章Windows套接字I/O模型 沈陽航空航天大學 將一個套接字置為非阻塞模式之后,將一個套接字置為非阻塞模式之后, Winsock API調(diào)用會調(diào)用會立即返回。大多數(shù)情況下,這些調(diào)用都會立即返回。大多數(shù)情況下,這些調(diào)用都會“失敗失敗”,并,并返回一個返回一個WSAEWOULDBLOCK錯誤,這意味著請求的錯誤,這意
11、味著請求的操作在調(diào)用期間沒有完成。操作在調(diào)用期間沒有完成。 例如在系統(tǒng)的輸入緩沖區(qū)中,尚不存在例如在系統(tǒng)的輸入緩沖區(qū)中,尚不存在“待決待決”的數(shù)據(jù),的數(shù)據(jù),那么那么recv(接收數(shù)據(jù))調(diào)用就會返回(接收數(shù)據(jù))調(diào)用就會返回WSAEWOULDBLOCK錯誤。通常,我們需要重復調(diào)用錯誤。通常,我們需要重復調(diào)用同一個函數(shù),直至獲得一個成功返回代碼。同一個函數(shù),直至獲得一個成功返回代碼。網(wǎng)絡程序設計 第三章Windows套接字I/O模型 沈陽航空航天大學 阻塞與非阻塞通信小結(jié)阻塞與非阻塞通信小結(jié)通信包括阻塞和非阻塞兩種模式。在網(wǎng)絡編程時,選通信包括阻塞和非阻塞兩種模式。在網(wǎng)絡編程時,選擇通信模式是一件很
12、重要的事情。對于不同的協(xié)議,擇通信模式是一件很重要的事情。對于不同的協(xié)議,阻塞通信和非阻塞通信有不同的表現(xiàn)。阻塞通信和非阻塞通信有不同的表現(xiàn)。網(wǎng)絡程序設計 第三章Windows套接字I/O模型 沈陽航空航天大學 阻塞與非阻塞通信小結(jié)阻塞與非阻塞通信小結(jié)對于對于UDPUDP協(xié)議而言,由于協(xié)議而言,由于UDPUDP沒有發(fā)送緩存,因此所有沒有發(fā)送緩存,因此所有UDPUDP協(xié)議即使在阻塞模式下也不會發(fā)生阻塞協(xié)議即使在阻塞模式下也不會發(fā)生阻塞. .網(wǎng)絡程序設計 第三章Windows套接字I/O模型 沈陽航空航天大學 每個每個TCPTCP套接口有一個發(fā)送緩沖區(qū),可以用套接口有一個發(fā)送緩沖區(qū),可以用SO_S
13、NDBUFSO_SNDBUF套接口選項套接口選項來改變這一緩沖區(qū)的大小。來改變這一緩沖區(qū)的大小。當應用進程調(diào)用當應用進程調(diào)用sendsend往套接口寫數(shù)據(jù)時,內(nèi)核從應用進程緩沖區(qū)往套接口寫數(shù)據(jù)時,內(nèi)核從應用進程緩沖區(qū)中拷貝所有數(shù)據(jù)到套接口的發(fā)送緩沖區(qū),如果套接口發(fā)送緩沖區(qū)中拷貝所有數(shù)據(jù)到套接口的發(fā)送緩沖區(qū),如果套接口發(fā)送緩沖區(qū)容不下應用程序的所有數(shù)據(jù),或者是應用進程的緩沖區(qū)大于套接容不下應用程序的所有數(shù)據(jù),或者是應用進程的緩沖區(qū)大于套接口的發(fā)送緩沖區(qū),或者是套接口的發(fā)送緩沖區(qū)中有別的數(shù)據(jù),應口的發(fā)送緩沖區(qū),或者是套接口的發(fā)送緩沖區(qū)中有別的數(shù)據(jù),應用進程將被掛起。內(nèi)核將不從用進程將被掛起。內(nèi)核將
14、不從sendsend返回。直到應用進程緩沖區(qū)中返回。直到應用進程緩沖區(qū)中的所有數(shù)據(jù)都拷貝到套接口發(fā)送緩沖區(qū)。的所有數(shù)據(jù)都拷貝到套接口發(fā)送緩沖區(qū)。所以,從寫一個所以,從寫一個TCPTCP套接口的套接口的sendsend調(diào)用成功返回僅僅表示我們可調(diào)用成功返回僅僅表示我們可以重新使用應用進程緩沖區(qū),它并不是告訴我們對方收到數(shù)據(jù)。以重新使用應用進程緩沖區(qū),它并不是告訴我們對方收到數(shù)據(jù)。TCPTCP發(fā)給對方的數(shù)據(jù),對方在收到數(shù)據(jù)時必須給矛確認,只有在發(fā)給對方的數(shù)據(jù),對方在收到數(shù)據(jù)時必須給矛確認,只有在收到對方的確認時,本方收到對方的確認時,本方TCPTCP才會把才會把TCPTCP發(fā)送緩沖區(qū)中的數(shù)據(jù)刪除。
15、發(fā)送緩沖區(qū)中的數(shù)據(jù)刪除。 UDPUDP因為是不可靠連接,不必保存應用進程的數(shù)據(jù)拷貝,應用進因為是不可靠連接,不必保存應用進程的數(shù)據(jù)拷貝,應用進程中的數(shù)據(jù)在沿協(xié)議棧向下傳遞時,以某種形式拷貝到內(nèi)核緩沖程中的數(shù)據(jù)在沿協(xié)議棧向下傳遞時,以某種形式拷貝到內(nèi)核緩沖區(qū),當數(shù)據(jù)鏈路層把數(shù)據(jù)傳出后就把內(nèi)核緩沖區(qū)中數(shù)據(jù)拷貝刪除。區(qū),當數(shù)據(jù)鏈路層把數(shù)據(jù)傳出后就把內(nèi)核緩沖區(qū)中數(shù)據(jù)拷貝刪除。因此它不需要一個發(fā)送緩沖區(qū)。寫因此它不需要一個發(fā)送緩沖區(qū)。寫UDPUDP套接口的套接口的sendsend返回表示應返回表示應用程序的數(shù)據(jù)或數(shù)據(jù)分片已經(jīng)進入鏈路層的輸出隊列,如果輸出用程序的數(shù)據(jù)或數(shù)據(jù)分片已經(jīng)進入鏈路層的輸出隊列,如
16、果輸出隊列沒有足夠的空間存放數(shù)據(jù),將返回錯誤隊列沒有足夠的空間存放數(shù)據(jù),將返回錯誤ENOBUFS. ENOBUFS. 網(wǎng)絡程序設計 第三章Windows套接字I/O模型 沈陽航空航天大學 阻塞與非阻塞通信小結(jié)阻塞與非阻塞通信小結(jié)對于面向連接的協(xié)議,在連接建立階段,阻塞與非阻對于面向連接的協(xié)議,在連接建立階段,阻塞與非阻塞也表現(xiàn)不一。在阻塞模式下,如果沒有連接請求到塞也表現(xiàn)不一。在阻塞模式下,如果沒有連接請求到達,則等待連接調(diào)用將阻塞直到有連接請求到達;但達,則等待連接調(diào)用將阻塞直到有連接請求到達;但在非阻塞模式下,如果沒有連接請求到達,等待連接在非阻塞模式下,如果沒有連接請求到達,等待連接調(diào)用
17、將直接返回。調(diào)用將直接返回。在連接建立階段,不管是阻塞模式還是非阻塞模式,在連接建立階段,不管是阻塞模式還是非阻塞模式,發(fā)起連接請求的一方總是會使調(diào)用它的進程阻塞,阻發(fā)起連接請求的一方總是會使調(diào)用它的進程阻塞,阻塞間隔最少等于到達服務器的一次往返時間。塞間隔最少等于到達服務器的一次往返時間。網(wǎng)絡程序設計 第三章Windows套接字I/O模型 沈陽航空航天大學通信模式對應用程序的設計方法也有直接的影響。在非通信模式對應用程序的設計方法也有直接的影響。在非阻塞模式下,應用程序必須不斷地輪詢是否有數(shù)據(jù)到達阻塞模式下,應用程序必須不斷地輪詢是否有數(shù)據(jù)到達或有連接請求到達?;蛴羞B接請求到達。這種輪詢的方
18、式耗費的這種輪詢的方式耗費的CPUCPU資源較大,要盡可能避免使用,資源較大,要盡可能避免使用,而在阻塞模式下則不存在這一問題,但其缺點是進程或而在阻塞模式下則不存在這一問題,但其缺點是進程或線程在執(zhí)行線程在執(zhí)行I/OI/O操作時將被阻塞而不能執(zhí)行其他的工作,操作時將被阻塞而不能執(zhí)行其他的工作,因此在單進程或單線程應用中不能使用這種模式。因此在單進程或單線程應用中不能使用這種模式。在多線程應用中比較適合采用阻塞模式,一個線程被阻在多線程應用中比較適合采用阻塞模式,一個線程被阻塞不影響其他線程的工作。塞不影響其他線程的工作。 網(wǎng)絡程序設計 第三章Windows套接字I/O模型 沈陽航空航天大學
19、阻塞和非阻塞套接字模式各存在著優(yōu)點和缺點阻塞和非阻塞套接字模式各存在著優(yōu)點和缺點 從概念的角度說,阻塞套接字更易使用。但在應付建立從概念的角度說,阻塞套接字更易使用。但在應付建立連接的多個套接字時,或在數(shù)據(jù)的收發(fā)量不均,時間不連接的多個套接字時,或在數(shù)據(jù)的收發(fā)量不均,時間不定時,卻顯得極難管理。定時,卻顯得極難管理。 而另一方面,由于需要編寫更多的代碼,以便在每個而另一方面,由于需要編寫更多的代碼,以便在每個Winsock調(diào)用中,對收到一個調(diào)用中,對收到一個WSAEWOULDBLOCK錯錯誤的可能性加以應付,那么非阻塞套接字便顯得有些難誤的可能性加以應付,那么非阻塞套接字便顯得有些難于操作。于
20、操作。 在這些情況下,可考慮使用在這些情況下,可考慮使用“套接字套接字I/O模型模型”,它有,它有助于應用程序通過一種異步方式,同時對助于應用程序通過一種異步方式,同時對一個或多個套一個或多個套接字接字上進行的通信事件加以管理。上進行的通信事件加以管理。網(wǎng)絡程序設計 第三章Windows套接字I/O模型 沈陽航空航天大學套接字套接字I/O模型模型套接字處于非阻塞模式時,何時可以讀套接字處于非阻塞模式時,何時可以讀/寫套接字?寫套接字?使用套接字使用套接字I/O模型模型Winsock2提供提供5種種I/O模型模型選擇模型(選擇模型(Select Model)異步選擇模型(異步選擇模型(WSAAs
21、yncSelect Model)事件選擇模型(事件選擇模型(WSAEventSelect Model)重疊模型(重疊模型(Overlapped Model)完成端口模型(完成端口模型(Completion Port Model)網(wǎng)絡程序設計 第三章Windows套接字I/O模型 沈陽航空航天大學操作系統(tǒng)對套接字I/O模型的支持情況所有Windows平臺都支持套接字以阻塞或非阻塞方式工作。然而,并非每種平臺都支持每一種I/O模型。在當前版本的Windows CE 中,僅提供了一個I/O模型。網(wǎng)絡程序設計 第三章Windows套接字I/O模型 沈陽航空航天大學 Select模型是模型是WinSoc
22、k中最常見的中最常見的I/O模型。模型。 通過調(diào)用通過調(diào)用select函數(shù)可以確定函數(shù)可以確定一個或多個套接字的狀態(tài)一個或多個套接字的狀態(tài),判斷套接字上是否有數(shù)據(jù),或者能否向一個套接字寫判斷套接字上是否有數(shù)據(jù),或者能否向一個套接字寫入數(shù)據(jù),或者出現(xiàn)意外。入數(shù)據(jù),或者出現(xiàn)意外。 目的是防止應用程序在套接字處于阻塞模式中時,在目的是防止應用程序在套接字處于阻塞模式中時,在一次一次I/O綁定調(diào)用(如綁定調(diào)用(如send或或recv)過程中,被迫進入)過程中,被迫進入“阻塞阻塞”狀態(tài);同時防止在套接字處于非阻塞模式中狀態(tài);同時防止在套接字處于非阻塞模式中時,產(chǎn)生時,產(chǎn)生WSAEWOULDBLOCK錯誤
23、。錯誤。2. select模型模型int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); 此函數(shù)用于檢測一個或多個套接字的狀態(tài)。套接字的狀態(tài)包括可讀、此函數(shù)用于檢測一個或多個套接字的狀態(tài)。套接字的狀態(tài)包括可讀、可寫、出錯??蓪憽⒊鲥e。 select函數(shù)函數(shù)u fd_set結(jié)構(gòu)結(jié)構(gòu)#define FD_SETSIZE 64typedef struct fd_set u_int fd_count; SOCKET fd_arrayFD_SETSIZE; f
24、d_set; u參數(shù)說明:參數(shù)說明:u 參數(shù)參數(shù)nfds會被忽略(設為會被忽略(設為0)。之所以仍然要提供這個參數(shù),只是為了保)。之所以仍然要提供這個參數(shù),只是為了保持與早期的持與早期的Berkeley套接字應用程序的兼容。套接字應用程序的兼容。u 函數(shù)形式函數(shù)形式 :參數(shù):參數(shù):fd_count:已設定:已設定socket的數(shù)量的數(shù)量 fd_array:socket列表,列表,F(xiàn)D_SETSIZE為最大為最大socket數(shù)量,建議不小于數(shù)量,建議不小于64(微軟建議)。(微軟建議)。網(wǎng)絡程序設計 第三章Windows套接字I/O模型 沈陽航空航天大學u參數(shù)參數(shù)readfds用于檢查可讀性,用
25、于檢查可讀性,readfds集合集合(讀集合讀集合)包括符合下包括符合下述任何一個條件的套接字:述任何一個條件的套接字: 有可以讀入數(shù)據(jù)的套接字。有可以讀入數(shù)據(jù)的套接字。 連接已經(jīng)關(guān)閉的套接字。連接已經(jīng)關(guān)閉的套接字。 如果如果listen已經(jīng)被調(diào)用,且有連接請求到達的套接字。該套接已經(jīng)被調(diào)用,且有連接請求到達的套接字。該套接字出現(xiàn)在此集合意味著字出現(xiàn)在此集合意味著accept函數(shù)調(diào)用會成功。函數(shù)調(diào)用會成功。u參數(shù)參數(shù)writefds用于寫數(shù)據(jù),用于寫數(shù)據(jù),writefds集合集合(寫集合寫集合)包括符合下述包括符合下述任何一個條件的套接字:任何一個條件的套接字: 有數(shù)據(jù)可以發(fā)出的套接字。有數(shù)據(jù)
26、可以發(fā)出的套接字。 如果已完成了對一個套接字的非阻塞連接調(diào)用的處理,那如果已完成了對一個套接字的非阻塞連接調(diào)用的處理,那么,該套接字出現(xiàn)在此集合意味著連接會成功。么,該套接字出現(xiàn)在此集合意味著連接會成功。u參數(shù)參數(shù)exceptfds用于例外數(shù)據(jù)用于例外數(shù)據(jù),exceptfds集合集合(例外集合例外集合)包括符包括符合下述任何一個條件的套接字:合下述任何一個條件的套接字: 有帶外數(shù)據(jù)可讀。有帶外數(shù)據(jù)可讀。 如果已完成了對一個套接字的非阻塞連接調(diào)用的處理,那如果已完成了對一個套接字的非阻塞連接調(diào)用的處理,那么,該套接字出現(xiàn)在此集合意味著連接嘗試失敗。么,該套接字出現(xiàn)在此集合意味著連接嘗試失敗。網(wǎng)絡
27、程序設計 第三章Windows套接字I/O模型 沈陽航空航天大學u參數(shù)參數(shù)timeout對應的是一個時間指針,它指向一個對應的是一個時間指針,它指向一個timeval結(jié)構(gòu),表示本次結(jié)構(gòu),表示本次select()調(diào)用最長的等待時間。調(diào)用最長的等待時間。struct timeval /timeval結(jié)構(gòu)結(jié)構(gòu)long tv_sec; /* seconds */long tv_usec; /* microseconds */;參數(shù):參數(shù): tv_sec:以秒為單位指定等待時間;:以秒為單位指定等待時間; tv_usec:以毫秒為單位指定等待時間:以毫秒為單位指定等待時間說明:說明: tv_sec= t
28、v_usec =0:檢查完套接字描述符后立即返回;:檢查完套接字描述符后立即返回; tv_sec 和和tv_usec 不全為不全為0,在等待時間內(nèi),對于被監(jiān)視的套接字描述,在等待時間內(nèi),對于被監(jiān)視的套接字描述符,如果有符,如果有I/O事件發(fā)生,事件發(fā)生, select()調(diào)用返回,否則一直等到超時;調(diào)用返回,否則一直等到超時; timeout指向指向NULL,則對于被監(jiān)視的套接字描述符,如果有,則對于被監(jiān)視的套接字描述符,如果有I/O事件事件發(fā)生,發(fā)生, select()調(diào)用才返回,否則一直等待。調(diào)用才返回,否則一直等待。網(wǎng)絡程序設計 第三章Windows套接字I/O模型 沈陽航空航天大學 函
29、數(shù)調(diào)用成功返回所有集合中滿足條件的套接字數(shù)量。同時傳入的套函數(shù)調(diào)用成功返回所有集合中滿足條件的套接字數(shù)量。同時傳入的套接字接字集合被更新集合被更新, select() 調(diào)用將調(diào)用將刪除刪除集合中不能進行指定操作的套集合中不能進行指定操作的套接字,接字, 集合中集合中保留保留滿足條件的套接字滿足條件的套接字 函數(shù)調(diào)用失敗,返回函數(shù)調(diào)用失敗,返回SOCKET_ERROR。 如超時,返回如超時,返回0。u返回值:返回值:int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *
30、timeout); 網(wǎng)絡程序設計 第三章Windows套接字I/O模型 沈陽航空航天大學選擇(select)模型處理方式網(wǎng)絡程序設計 第三章Windows套接字I/O模型 沈陽航空航天大學 假定想測試一個套接字是否假定想測試一個套接字是否“可讀可讀”,必須將該套接字,必須將該套接字增添到增添到readfds集合,再等待集合,再等待select函數(shù)完成。函數(shù)完成。 select完成之后,必須判斷該套接字是否仍在完成之后,必須判斷該套接字是否仍在readfds集合集合中,若在,便表明該套接字中,若在,便表明該套接字“可讀可讀”,可從它上面讀取,可從它上面讀取數(shù)據(jù)。數(shù)據(jù)。 select使用使用網(wǎng)絡程
31、序設計 第三章Windows套接字I/O模型 沈陽航空航天大學l 使用使用FD_ZERO宏,初始化自己感興趣的每一個宏,初始化自己感興趣的每一個fd_set集合。集合。l 使用使用FD_SET宏,將要檢查的套接字加入到一個集合中。宏,將要檢查的套接字加入到一個集合中。l設置等待時間,對設置等待時間,對timeval中中tv_sec和和tv_usec字段進行設置。字段進行設置。l 調(diào)用調(diào)用select函數(shù)。函數(shù)。lselect正確返回時,使用正確返回時,使用FD_ISSET檢查一個選定的套接字是否在指定的集合檢查一個選定的套接字是否在指定的集合中。中。l針對不同集合的套接字做出不同的操作。針對不
32、同集合的套接字做出不同的操作。 select使用使用注意:如果不想檢查某個集合,則可以將該集合對應的參數(shù)位設置為空,注意:如果不想檢查某個集合,則可以將該集合對應的參數(shù)位設置為空,但但三個參數(shù)不能同時全為空三個參數(shù)不能同時全為空null。Winsock提供了下列宏操作,對幾個提供了下列宏操作,對幾個fd_set類型集合進行處理與檢查:類型集合進行處理與檢查: FD_CLR(s,*set) :從:從set中刪除套接字中刪除套接字s。 FD_ISSET (s,*set) : 檢查檢查s是否是否set集合的一名成員。集合的一名成員。 FD_SET (s,*set) : 將套接字將套接字s加入集合加入
33、集合set。 FD_ZERO ( *set ) :將:將set初始化成空集合。初始化成空集合。u 對一個或多個套接字檢查的全過程對一個或多個套接字檢查的全過程網(wǎng)絡程序設計 第三章Windows套接字I/O模型 沈陽航空航天大學#include #include #pragma comment(lib, WS2_32) / 鏈接到鏈接到WS2_32.lib#define PORT 6000/ 此服務器監(jiān)聽的端口號此服務器監(jiān)聽的端口號#define BUFFERLEN 1024 /數(shù)據(jù)緩沖區(qū)大小數(shù)據(jù)緩沖區(qū)大小 select編程實例編程實例 服務器程序服務器程序void main()/載入載入Win
34、sock庫庫WSADATA wsaData;WORD version = MAKEWORD(2, 2);int ret = WSAStartup(version, &wsaData);if(ret != 0)printf( 加載加載Winsock庫錯誤庫錯誤! n);return ;網(wǎng)絡程序設計 第三章Windows套接字I/O模型 沈陽航空航天大學/ 創(chuàng)建監(jiān)聽套接字創(chuàng)建監(jiān)聽套接字SOCKET sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);if ( INVALID_SOCKET =sListen) printf( 創(chuàng)建套接字失?。簞?chuàng)建套
35、接字失?。?dn,WSAGetLastError();return ; u_long ul=1; if (SOCKET_ERROR= ioctlsocket(sListen,FIONBIO,(unsigned long *)&ul) printf(設置套接字為非阻塞模式失敗設置套接字為非阻塞模式失敗!n); /設置服務器端地址設置服務器端地址 sockaddr_in addrSrv;/聲明服務器端地址聲明服務器端地址 addrSrv.sin_family = AF_INET;/Internet協(xié)議地址族協(xié)議地址族 addrSrv.sin_addr.S_un.S_addr = INADDR_AN
36、Y;/系統(tǒng)自動指定系統(tǒng)自動指定IP addrSrv.sin_port = htons(PORT);/把把16位端口轉(zhuǎn)換為網(wǎng)絡字節(jié)位端口轉(zhuǎn)換為網(wǎng)絡字節(jié)網(wǎng)絡程序設計 第三章Windows套接字I/O模型 沈陽航空航天大學/ 綁定套接字到本地機器綁定套接字到本地機器if(SOCKET_ERROR= bind(sListen, (sockaddr*)&addrSrv, sizeof(addrSrv) )printf( 綁定失敗綁定失敗n);return;listen(sListen, 5); / 進入監(jiān)聽模式進入監(jiān)聽模式char sendBufBUFFERLEN;/用戶發(fā)送緩沖區(qū)用戶發(fā)送緩沖區(qū)char
37、 recvBufBUFFERLEN;/用戶接收緩沖區(qū)用戶接收緩沖區(qū)int sendlen, recvlen;/發(fā)送發(fā)送接收數(shù)據(jù)長度接收數(shù)據(jù)長度 / select模型處理過程模型處理過程fd_set fdSocket, fdRead, fdWrite ; /聲明套接字集合聲明套接字集合FD_ZERO(&fdSocket);/ 初始化一個套接字集合初始化一個套接字集合fdSocketFD_ZERO(&fdRead);/ 初始化一個套接字集合初始化一個套接字集合fdReadFD_ZERO(&fdWrite);/ 初始化一個套接字集合初始化一個套接字集合fdWriteFD_SET(sListen, &
38、fdSocket);/添加監(jiān)聽套接字到這個集合添加監(jiān)聽套接字到這個集合 printf(select模型服務器正在運行模型服務器正在運行.n); while(TRUE)/進入無限循環(huán),等待客戶的連接請求進入無限循環(huán),等待客戶的連接請求fdRead=fdSocket; fdWrite=fdSocket;/設置讀寫集合設置讀寫集合int i, nRet;nRet = select(0, &fdRead, &fdWrite, NULL, NULL);if(FD_ISSET(sListen, &fdRead)/說明有新連接到來說明有新連接到來讀集合讀集合 for(i=0; i(int)fdSocket.
39、fd_count; i+) if(FD_ISSET(fdSocket.fd_arrayi, &fdRead) /判斷套接字在讀集合,處理接收過程判斷套接字在讀集合,處理接收過程 /for end /while end closesocket(sListen);/關(guān)閉監(jiān)聽套接字關(guān)閉監(jiān)聽套接字 WSACleanup();/釋放釋放Winsock庫庫 return; /main endif(FD_ISSET(sListen, &fdRead)/說明有新連接到來說明有新連接到來sockaddr_in clientAddr; int nAddrLen = sizeof(clientAddr);SOCKE
40、T sNewClient = accept(sListen, (SOCKADDR*)&clientAddr, &nAddrLen);ul=1; /設置套接字為非阻塞模式設置套接字為非阻塞模式ioctlsocket(sNewClient,FIONBIO,(unsigned long *)&ul) ;/輸出客戶端的輸出客戶端的IP地址和端口地址和端口printf(來自來自%s,端口端口%d的一個客戶訪問服務器的一個客戶訪問服務器n,inet_ntoa(clientAddr.sin_addr),ntohs(clientAddr.sin_port);FD_SET(sNewClient, &fdSock
41、et);/增加到臨時集合增加到臨時集合fdWrite=fdSocket;/設置設置寫集合寫集合nRet = select(0, NULL, &fdWrite, NULL, NULL);sprintf(sendBuf,歡迎來自歡迎來自%s,端口端口%d的客戶訪問的客戶訪問!,inet_ntoa(clientAddr.sin_addr),ntohs(clientAddr.sin_port);if(FD_ISSET(sNewClient, &fdWrite)send(sNewClient, sendBuf, strlen(sendBuf)+1, 0);continue;for(i=0; i(int)
42、fdSocket.fd_count; i+)if(FD_ISSET(fdSocket.fd_arrayi, &fdRead)/判斷套接字在判斷套接字在讀集合讀集合,處理接收過程,處理接收過程recvlen = recv(fdSocket.fd_arrayi, recvBuf, sizeof(recvBuf), 0);if(SOCKET_ERROR= recvlen)/ 連接關(guān)閉連接關(guān)閉printf(接收數(shù)據(jù)錯誤接收數(shù)據(jù)錯誤,一個客戶端關(guān)閉一個客戶端關(guān)閉.n);closesocket(fdSocket.fd_arrayi);FD_CLR(fdSocket.fd_arrayi, &fdSocket
43、);else/ 可讀可讀recvBufrecvlen=0;printf(收到客戶機說收到客戶機說:%s ; 接收字節(jié)接收字節(jié)%dn, recvBuf,recvlen); if(FD_ISSET(fdSocket.fd_arrayi, &fdWrite) /判斷套接字在判斷套接字在寫集合寫集合,處理發(fā)送過程,處理發(fā)送過程/可讀可讀/在讀集合在讀集合 /for endSrv服務端服務端 具體接收過程具體接收過程網(wǎng)絡程序設計 第三章Windows套接字I/O模型 沈陽航空航天大學if(FD_ISSET(fdSocket.fd_arrayi, &fdWrite)/判斷套接字在判斷套接字在寫集合寫集合,
44、處理發(fā)送過程,處理發(fā)送過程sprintf(sendBuf,I am a server!);sendlen=send(fdSocket.fd_arrayi, sendBuf, strlen(sendBuf)+1, 0);if(SOCKET_ERROR= sendlen)/ 連接關(guān)閉連接關(guān)閉printf(發(fā)送數(shù)據(jù)錯誤發(fā)送數(shù)據(jù)錯誤.n);/在寫集合在寫集合Ssd服務端服務端 具體發(fā)送過程具體發(fā)送過程網(wǎng)絡程序設計 第三章Windows套接字I/O模型 沈陽航空航天大學 客戶端程序客戶端程序#include #include #pragma comment(lib, WS2_32) / 鏈接到鏈接到WS
45、2_32.lib#define PORT 6000/ 此服務器監(jiān)聽的端口號此服務器監(jiān)聽的端口號#define BUFFERLEN 1024 /數(shù)據(jù)緩沖區(qū)大小數(shù)據(jù)緩沖區(qū)大小void main()/載入載入Winsock庫庫WSADATA wsaData;WORD version = MAKEWORD(2, 2);int ret = WSAStartup(version, &wsaData);if(ret != 0)printf( 加載加載Winsock庫錯誤庫錯誤! n);return ;網(wǎng)絡程序設計 第三章Windows套接字I/O模型 沈陽航空航天大學 /創(chuàng)建套接字創(chuàng)建套接字 SOCKET
46、sockClient=socket(AF_INET,SOCK_STREAM,0);if ( INVALID_SOCKET =sockClient) printf( 創(chuàng)建套接字失敗:創(chuàng)建套接字失?。?dn,WSAGetLastError();return ;u_long ul=1;if (SOCKET_ERROR= ioctlsocket(sockClient,FIONBIO,(unsigned long *)&ul) printf(設置套接字為非阻塞模式失敗設置套接字為非阻塞模式失敗!n);SOCKADDR_IN addrSrv;addrSrv.sin_family=AF_INET;addrS
47、rv.sin_addr.S_un.S_addr=inet_addr(127.0.0.1);addrSrv.sin_port=htons(PORT);/把把16位主機字節(jié)轉(zhuǎn)換為網(wǎng)絡字節(jié)位主機字節(jié)轉(zhuǎn)換為網(wǎng)絡字節(jié) connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(addrSrv);網(wǎng)絡程序設計 第三章Windows套接字I/O模型 沈陽航空航天大學char sendBufBUFFERLEN, recvBufBUFFERLEN;/用戶發(fā)送接收緩沖區(qū)用戶發(fā)送接收緩沖區(qū)int sendlen, recvlen;/發(fā)送接收數(shù)據(jù)長度發(fā)送接收數(shù)據(jù)長度fd_set fdW
48、rite, fdRead, fdExcept; /聲明集合聲明集合FD_ZERO(&fdWrite); FD_ZERO(&fdRead); FD_ZERO(&fdExcept); /清空清空FD_SET(sockClient, &fdWrite); FD_SET(sockClient, &fdExcept); /設置集合設置集合int nRet =select(0, NULL,&fdWrite, &fdExcept, NULL);if(SOCKET_ERROR=nRet) printf(select檢查連接情況時,發(fā)生錯誤檢查連接情況時,發(fā)生錯誤!n);elseif(FD_ISSET(sock
49、Client, &fdExcept)printf(sockClient 出現(xiàn)在出現(xiàn)在異常集合異常集合中中, 連接失敗連接失敗,退出程序退出程序.n); return ;if(FD_ISSET(sockClient, &fdWrite) printf(sockClient 出現(xiàn)在出現(xiàn)在寫集合寫集合中中, 連接成功連接成功,準備通信準備通信.n);網(wǎng)絡程序設計 第三章Windows套接字I/O模型 沈陽航空航天大學printf(客戶機正在運行客戶機正在運行.n);while(TRUE)/進入無限循環(huán)進入無限循環(huán)FD_SET(sockClient, &fdRead); FD_SET(sockClie
50、nt, &fdWrite);nRet=select(0, &fdRead,&fdWrite, &fdExcept, NULL);if(nRet=SOCKET_ERROR)printf(select發(fā)生讀寫集合檢查錯誤發(fā)生讀寫集合檢查錯誤!); break;if(FD_ISSET(sockClient, &fdRead) /從服務器端接收數(shù)據(jù)從服務器端接收數(shù)據(jù)if(FD_ISSET(sockClient, &fdWrite) /向服務器端發(fā)送數(shù)據(jù)向服務器端發(fā)送數(shù)據(jù)Sleep(2000); /暫停暫停2秒秒/while endclosesocket(sockClient);/關(guān)閉套接字關(guān)閉套接字W
51、SACleanup();/釋放釋放Winsock庫庫 /main end網(wǎng)絡程序設計 第三章Windows套接字I/O模型 沈陽航空航天大學if(FD_ISSET(sockClient, &fdRead)/從服務器端接收數(shù)據(jù)從服務器端接收數(shù)據(jù)recvlen=recv(sockClient,recvBuf,sizeof(recvBuf),0);if (SOCKET_ERROR=recvlen) printf(接收數(shù)據(jù)錯誤!連接已經(jīng)關(guān)閉接收數(shù)據(jù)錯誤!連接已經(jīng)關(guān)閉);break;printf(收到服務器說收到服務器說:%s ; 接收字節(jié)接收字節(jié)%dn,recvBuf,recvlen);Crv客戶端客
52、戶端 具體接收過程具體接收過程網(wǎng)絡程序設計 第三章Windows套接字I/O模型 沈陽航空航天大學if(FD_ISSET(sockClient, &fdWrite)/向服務器端發(fā)送數(shù)據(jù)向服務器端發(fā)送數(shù)據(jù)sprintf(sendBuf,I am a Client!);/strlen(sendBuf)+1 把字符串的結(jié)束符把字符串的結(jié)束符0一塊發(fā)送一塊發(fā)送sendlen=send(sockClient,sendBuf,strlen(sendBuf)+1,0);if (SOCKET_ERROR=sendlen) printf(發(fā)送數(shù)據(jù)錯誤!發(fā)送數(shù)據(jù)錯誤!);break;printf(“成功發(fā)送數(shù)據(jù)成
53、功發(fā)送數(shù)據(jù):%s; 發(fā)送字節(jié)發(fā)送字節(jié)%dn,sendBuf,sendlen);Csd客戶端客戶端 具體發(fā)送過程具體發(fā)送過程網(wǎng)絡程序設計 第三章Windows套接字I/O模型 沈陽航空航天大學select模型服務器正在運行模型服務器正在運行.u服務器端程序運行結(jié)果:服務器端程序運行結(jié)果:sockClient 出現(xiàn)在寫集合中出現(xiàn)在寫集合中, 連接成功連接成功,準備通信準備通信.收到服務器說收到服務器說:歡迎來自歡迎來自127.0.0.1,端口端口1060的客戶訪問的客戶訪問! ; 接收字節(jié)接收字節(jié)57成功發(fā)送數(shù)據(jù)成功發(fā)送數(shù)據(jù):I am a Client! ; 發(fā)送字節(jié)發(fā)送字節(jié)15收到服務器說收到服
54、務器說:I am a server! ; 接收字節(jié)接收字節(jié)15u客戶端程序運行結(jié)果:客戶端程序運行結(jié)果:sockClient 出現(xiàn)在寫集合中出現(xiàn)在寫集合中, 連接成功連接成功,準備通信準備通信.收到服務器說收到服務器說:歡迎來自歡迎來自127.0.0.1,端口端口1061的客戶訪問的客戶訪問! ; 接收字節(jié)接收字節(jié)57成功發(fā)送數(shù)據(jù)成功發(fā)送數(shù)據(jù):I am a Client! ;發(fā)送字節(jié)發(fā)送字節(jié)15收到服務器說收到服務器說:I am a server! ; 接收字節(jié)接收字節(jié)15來自來自127.0.0.1,端口端口1060的一個客戶訪問服務器的一個客戶訪問服務器收到客戶機說收到客戶機說:I am a
55、 Client! ; 接收字節(jié)接收字節(jié)15來自來自127.0.0.1,端口端口1061的一個客戶訪問服務器的一個客戶訪問服務器收到客戶機說收到客戶機說:I am a Client! ; 接收字節(jié)接收字節(jié)15網(wǎng)絡程序設計 第三章Windows套接字I/O模型 沈陽航空航天大學 select模型的優(yōu)點:可以在單線程內(nèi)管理多個模型的優(yōu)點:可以在單線程內(nèi)管理多個套接字,最大套接字數(shù)量取決于套接字,最大套接字數(shù)量取決于FD_SETSIZE的大小,的大小,Winsock2.h中定義為中定義為64,用戶也可自,用戶也可自行定義,但不能超過行定義,但不能超過1024。 缺點:調(diào)用缺點:調(diào)用select前后對所
56、有套接字都要進行前后對所有套接字都要進行遍歷操作,以便設置和檢查。當遍歷操作,以便設置和檢查。當FD_SETSIZE太大時,服務器性能明顯下降。太大時,服務器性能明顯下降。3. Windows程序基本工作原理程序基本工作原理鍵盤鍵盤鼠標鼠標操作系統(tǒng)操作系統(tǒng)顯示器顯示器聲卡聲卡 輸入輸出設備輸入輸出設備應用程序應用程序應用應用程序程序 43消息消息隊列隊列12 應用程序、操作系統(tǒng)、輸入輸出設備相互關(guān)系應用程序、操作系統(tǒng)、輸入輸出設備相互關(guān)系網(wǎng)絡程序設計 第三章Windows套接字I/O模型 沈陽航空航天大學 Windows程序的進行依靠外部發(fā)生的事件來驅(qū)動。程序的進行依靠外部發(fā)生的事件來驅(qū)動。程
57、序不斷等待任何可能的程序不斷等待任何可能的輸入輸入(如從鍵盤或鼠標如從鍵盤或鼠標),然后再做適,然后再做適當?shù)奶幚怼.數(shù)奶幚怼?例如:用戶在某個程序活動時,按下某個鍵,操作系統(tǒng)馬上例如:用戶在某個程序活動時,按下某個鍵,操作系統(tǒng)馬上會感知到這件事情,并能知道用戶按下的是哪一個鍵會感知到這件事情,并能知道用戶按下的是哪一個鍵(1) ,然,然后把這個事件以后把這個事件以消息消息形式存入消息隊列,如果該消息剛好在形式存入消息隊列,如果該消息剛好在隊頭,應用程序就獲得該消息隊頭,應用程序就獲得該消息(2) ,然后應用程序可以,然后應用程序可以通知通知(3)操作系統(tǒng)把按下鍵的具體信息輸出到屏幕上操作系統(tǒng)
58、把按下鍵的具體信息輸出到屏幕上(4) 。 (1) 操作系統(tǒng)捕獲操作系統(tǒng)捕獲輸入輸入(如從鍵盤或鼠標如從鍵盤或鼠標) 。 (2) 捕獲的輸入捕獲的輸入以以消息消息形式形式(一種數(shù)據(jù)結(jié)構(gòu)一種數(shù)據(jù)結(jié)構(gòu))放入放入消息隊列消息隊列,應用程序從消息隊列中取走消息。應用程序從消息隊列中取走消息。 (3) 應用程序收到消息后,根據(jù)程序的功能需要來應用程序收到消息后,根據(jù)程序的功能需要來通知通知操作操作系統(tǒng)。系統(tǒng)。 (4) 操作系統(tǒng)執(zhí)行相應的功能。操作系統(tǒng)執(zhí)行相應的功能。 這里的通知:實質(zhì)上是對這里的通知:實質(zhì)上是對操作系統(tǒng)操作系統(tǒng)API函數(shù)的調(diào)用。函數(shù)的調(diào)用。應用程序?qū)@些函數(shù)的調(diào)應用程序?qū)@些函數(shù)的調(diào)用就叫
59、做系統(tǒng)調(diào)用。用就叫做系統(tǒng)調(diào)用。網(wǎng)絡程序設計 第三章Windows套接字I/O模型 沈陽航空航天大學typedef struct tagMSG / 消息消息 HWND hwnd;/窗口資源的標識窗口資源的標識 ,類似于指針,類似于指針 UINT message;/標識一個消息標識一個消息 如如W M_CHAR按下一個鍵按下一個鍵 WPARAM wParam;/整型整型 關(guān)于這個消息的附加信息關(guān)于這個消息的附加信息 如按下如按下a / WM_CHAR消息消息 wParam知道按下的是哪一個字母知道按下的是哪一個字母 LPARAM lParam;/整型整型 關(guān)于這個消息的附加信息關(guān)于這個消息的附加信
60、息 , 如如 / WM_LBUTTONDOWN消息消息lParam存放鼠標左鍵按下位置的坐標存放鼠標左鍵按下位置的坐標 DWORD time;/32位整數(shù)位整數(shù),消息被傳遞出去時的時間消息被傳遞出去時的時間 POINT pt;/點結(jié)構(gòu)體變量,消息發(fā)送時屏幕光標的位置點結(jié)構(gòu)體變量,消息發(fā)送時屏幕光標的位置 MSG; /這里的類型定義,目的是為了含義更清晰這里的類型定義,目的是為了含義更清晰typedef unsigned int UINT; typedef long LONG; typedef UINT WPARAM; typedef LONG LPARAM;不同消息類型,對應的附加信息含義不同
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年河北省退役軍人事務廳下屬事業(yè)單位招聘考試筆試試題【答案】
- 2025年農(nóng)商銀行反洗錢知識競賽培訓考試試題【答案】
- 項目日常管理制度
- 消防自然災害應急救援預案
- 領(lǐng)導干部學習黨的.教育實踐活動心得體會
- 2025年涂鍍產(chǎn)品:鍍鋁鋅合作協(xié)議書
- 消防員辭職保證書
- 翔隆花園人貨梯專項方案
- 湘藝版四年級上冊音樂《卓瑪》教案 (一)
- 2025年汽車內(nèi)外飾件合作協(xié)議書
- DB31/T 560-2011道路清掃保潔作業(yè)道班房設置和設計要求
- 2025-2030廢電池回收產(chǎn)業(yè)發(fā)展分析及發(fā)展趨勢與投資前景預測報告
- 2026屆高職單招考試大綱英語詞匯(音標版)
- 中小學辦學思想凝練的主要路徑
- 危險性較大的分部分項工程專項施工方案嚴重缺陷清單(試行)2025解讀
- 2024執(zhí)業(yè)獸醫(yī)資格證考試真題及答案
- 鼠標操作測試題及答案
- 2023年福建省松溪縣事業(yè)單位公開招聘輔警35名筆試題帶答案
- 浙江國企招聘2025紹興市鏡湖開發(fā)集團有限公司下屬國企招聘11人筆試參考題庫附帶答案詳解
- 店鋪轉(zhuǎn)讓帶技術(shù)合同協(xié)議
- 2025年第九屆“學憲法、講憲法”活動知識競賽測試題庫及答案
評論
0/150
提交評論