版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
C#.NET編程技術第12講.NET遠程通信1內容提要通信模型概述套接字通信編程面向對象的通信.NETRemoting基本原理.NETRemoting通信編程2內容提要通信模型概述套接字通信編程面向對象的通信.NETRemoting基本原理.NETRemoting通信編程3通信模型概述什么是通信?兩個或多個物理或邏輯實體之間的數(shù)據(jù)交互計算機通信的要素:信道通信地址通信協(xié)議4信道“信道”不是一個有明確意義的名詞在不同的應用場景下,可能具有不同的含義物理的信道光纖信道,無線頻點,CDMA碼點邏輯的信道Ethernet,F(xiàn)DDI,ATM,X.25TCP,UDP,HTTP,IPC本講所說的信道,指將數(shù)據(jù)從通信一端傳遞到另一端的邏輯路徑,例如TCP虛電路5通信地址與通信協(xié)議通信地址不是一個孤立的概念,常常是與通信協(xié)議相配套的。在TCP/IP網(wǎng)絡的不同層次上有不同的編址方式和通信協(xié)議,例如:——數(shù)據(jù)鏈路層:MAC地址,Ethernet協(xié)議——網(wǎng)絡層:IP地址,IP協(xié)議——傳輸層:IP地址+端口,TCP/UDP協(xié)議——應用層:域名/IP地址+端口,HTTP協(xié)議本講關注的是傳輸層和應用層通信。6內容提要通信模型概述套接字通信編程面向對象的通信.NETRemoting基本原理.NETRemoting通信編程7套接字通信在TCP/IP網(wǎng)絡上的傳統(tǒng)通信模型起源于UNIX操作系統(tǒng)以一個“套接字(socket)”作為通信的端點,數(shù)據(jù)在兩個socket之間傳遞套接字通信不關心應用層數(shù)據(jù)的格式8套接字通信示例(TCP服務器端)//創(chuàng)建一個偵聽套接字SocketsListen=newSocket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);//偵聽套接字綁定地址sListen.Bind(newIPEndPoint(IPAddress.Any,8960));//偵聽到來的連接sListen.Listen();//接受連接到一個新的套接字SocketsAccecpt=sListen.Accept();//使用新的套接字接收和發(fā)送數(shù)據(jù)sAccecpt.Send(…)9.NET類庫對套接字通信的封裝為了使用方便,.NET針對不同的協(xié)議,對套接字通信進行了封裝傳輸層協(xié)議封裝TcpListener/TcpClient/UdpClient用于執(zhí)行TCP連接通信和UDP無連接通信UDP是無連接的、基于數(shù)據(jù)包的協(xié)議,數(shù)據(jù)包所承載通信數(shù)據(jù)的格式需自行定義;TCP是基于流的協(xié)議,單次接收不一定能收到足夠的數(shù)據(jù)。因此必須自行制定協(xié)議,確保收到了足夠的數(shù)據(jù)。10.NET類庫對套接字通信的封裝(續(xù))應用層協(xié)議封裝WebClientWebRequestWebResponse用于以URI標定地址的通信,一般都是請求/響應模式具體派生類HttpWebRequest/HttpWebResponse11使用套接字封裝類的示例//發(fā)起到:80的TCP連接,并收發(fā)數(shù)據(jù)TcpClienttcpClient=newTcpClient("",80);using(Streams=tcpClient.GetStream()){s.Read();s.Write();}//發(fā)起到的HTTP請求,并獲得響應using(HttpWebRequesthttpReq=HttpWebRequest.Create("")asHttpWebRequest){HttpWebResponsehttpRes=httpReq.GetResponse();}12套接字及封裝通信類的特點優(yōu)點:一脈傳承自UNIX,是經典的網(wǎng)絡通信編程模型,C/C++程序員容易入手使用簡單,含義明確不足:程序員需熟悉通信協(xié)議及TCP/IP協(xié)議棧如果使用其它通信,如IPC、MSMQ,程序員同樣需熟悉具體協(xié)議需自行維護通信數(shù)據(jù)格式,及通信的完整性這意味著:程序員必須消耗額外的精力用于學習通信協(xié)議的底層細節(jié),和設計可靠的數(shù)據(jù)傳輸流程。而這種學習和設計常常不是軟件項目所要求的業(yè)務工作,而只是一些潛在的背景知識和底層架構13內容提要通信模型概述套接字通信編程面向對象的通信.NETRemoting基本原理.NETRemoting通信編程14面向對象的通信.NET是面向對象的語言而使用socket的通信,傳遞的是無格式數(shù)據(jù)能否在通信中傳遞對象?通信中傳遞對象的好處:與面向對象編程風格保持一致,無需關注通信中的數(shù)據(jù)流格式及數(shù)據(jù)傳遞的完整性;與常規(guī)編程方式一樣使用對象,不關心底層如何通信的,從而集中全部精力在業(yè)務功能上。15從編程角度看通信的實質從編程的角度看,什么是通信?所謂通信,就是函數(shù)調用。//偵聽到來的連接sListen.Listen();//接受連接到一個新的套接字SocketsAccept=sListen.Accept();//使用新的套接字接收和發(fā)送數(shù)據(jù)byte[]data={1,2,3,4};sAccept.Send(data);byte[]rcvData=newbyte[5];sAccept.Receive(rcvData);發(fā)送數(shù)據(jù),就是調用一個函數(shù)(Send)并把要發(fā)送的數(shù)據(jù)(data)作為形參傳入。接收數(shù)據(jù),就是調用一個函數(shù)(Receive)并把要存儲收到數(shù)據(jù)的緩沖區(qū)作為形參傳入。16基于socket通信的示意圖SocketSocket.Send通信對象:通信函數(shù):信道Socket.ReceiveSocket字節(jié)數(shù)據(jù)17從編程角度看通信的實質(續(xù))在基于socket的通信中,被調用的函數(shù)都是固定類型(Socket/TcpClient/WebRequest等)的方法傳遞的數(shù)據(jù)則是無格式的連續(xù)字節(jié)數(shù)據(jù)的傳入和接收都是使用函數(shù)形參發(fā)送和接收使用不同的函數(shù)那么,是否可以……以任意類型的方法作為通信函數(shù)?傳遞的數(shù)據(jù)能否是有意義的對象?以函數(shù)返回值的方式返回數(shù)據(jù)?發(fā)送端、接收端的函數(shù),能否是同一個?18面向對象通信的示意圖MyObjectResonseSocket.ExecReq(Requestreq)通信對象:通信函數(shù):信道MyObjectResonseSocket.ExecReq(Requestreq)任意對象作為通信對象傳遞的數(shù)據(jù)是有意義的(一個Request類型對象)以函數(shù)返回值的方式返回數(shù)據(jù)(一個Response類型對象)MyObjectobj=newMyObject();Requestreq=newRequest(…);Responseres=obj.ExecReq(req);這樣的通信,怎樣編程?這與平常的編程沒有任何區(qū)別,根本看不出通信的存在!發(fā)送和接收函數(shù),是同一個(ExecReq)19面向對象通信面向對象通信與面向對象本地編程,在代碼上完全一樣。二者區(qū)別在于:參數(shù)傳到了本地,還是傳到了遠程機器函數(shù)的執(zhí)行,是在本地還是在遠程機器面向對象通信編程:看起來像是調用了個本地函數(shù),就得到了結果;實際上參數(shù)是傳遞到了遠程機器上,而函數(shù)也是在遠程機器上執(zhí)行的。20面向對象通信的幾個要點信道數(shù)據(jù)通過什么信道傳遞的(TCP/HTTP/IPC…)通信對象通信雙方使用的通信對象是什么在socket通信中,socket標識通信端點;而在面向對象通信中,端點是任何對象,我們叫做通信對象封裝格式面向對象通信傳遞的是對象,而各類信道只能傳遞無格式的字節(jié)串或文本,那么如何將對象封裝成字節(jié)串或文本,且不丟失對象本身的信息21.NET3.5支持的主要通信模型.NETRemoting僅能使用在.NET平臺上“信道”可使用HTTP/TCP/IPC,也可以自定義可以用Binary/XML/SOAP封裝通信中的對象WebServices與平臺無關的通信模型,兼容性好“信道”只能使用HTTP只能用SOAP封裝通信中的對象WindowsCommunicationFoundation(WCF).NET3.0提供的統(tǒng)一通信模型,融合了.NETRemoting/WebServices/MSMQ等多種通信方式后兩種通信模型,我們在講完ASP.NET之后再講述22內容提要通信模型概述套接字通信編程面向對象的通信.NETRemoting基本原理.NETRemoting通信編程23.NETRemoting一種面向對象通信模式信道:TCP/HTTP/IPC,可自行擴展定義通信對象:自定義引用類型封裝格式:TCP和IPC信道使用Binary,HTTP信道使用SOAP負責兩個應用程序域之間的通信回顧:什么是應用程序域?24.NETRemoting的幾個術語代理、消息、信道、格式化程序對象封送方式MBR(引用封送)和MBV(值封送)MBR激活類型WKO(知名對象)和CAO(客戶端激活對象)WKO類型狀態(tài)配置單例和單一調用25.NETRemoting通信示意圖客戶端服務器端調度程序格式化程序透明代理信道格式化程序真實代理遠程對象26.NETRemoting通信示意圖客戶端服務器端調度程序格式化程序透明代理信道格式化程序真實代理遠程對象“代理”的作用,是給客戶端提供通信對象的接口,使客戶端認為自己好像在調用一個本地對象,而實際上通信對象的實體在服務器端?!按怼必撠熃邮湛蛻舳溯斎氲恼{用參數(shù),然后將這些參數(shù)封裝成“消息”并傳遞給服務器端。所謂“消息”,就是一個實現(xiàn)了IMessage接口的對象。27.NETRemoting通信示意圖客戶端服務器端調度程序格式化程序透明代理信道格式化程序真實代理遠程對象“格式化程序”負責將要傳遞給服務器端的調用參數(shù)進行變換,以適應信道。例如對于TCP和IPC信道,將被變換成二進制格式(Binary)。這就是前述三要點中的“封裝格式”。28.NETRemoting通信示意圖客戶端服務器端調度程序格式化程序透明代理信道格式化程序真實代理遠程對象.NET2.0以后支持的“信道”有三種:TCP、IPC和HTTP。TCP與HTTP的區(qū)別(1)TCP是全雙工的通信信道;而HTTP本質上是單工通信,客戶端發(fā)送請求,服務器回送響應。(2)TCP的載荷是二進制數(shù)據(jù),HTTP的載荷是可打印文本字符。29對象封送方式一個對象(實質上是對象實例),怎樣從通信一端跑到另一端?MBR:引用封送當服務器端把MBR對象傳給客戶端時,客戶端所得到的只是對服務器端對象的一個引用,而對象實體仍在服務器端這意味著:客戶端對MBR對象任何方法/屬性的訪問,都會通過代理傳遞到服務器端執(zhí)行,而非本地執(zhí)行“通信對象”必須是MBR,否則無法完成我們期望的功能30MBR對象傳遞示意圖客戶端服務器端信道//MyObject是遠程對象類型MyObjectobj=newMyObject();obj.SetData(stringstr);MBRObjmbr=obj.GetObj();MyObject對象實例看起來似乎創(chuàng)建了一個本地對象實例,實際上這個實例是在服務器端創(chuàng)建,而非本地??雌饋硭坪跽{用了本地對象的一個函數(shù),實際上此函數(shù)是在服務器端執(zhí)行的,參數(shù)通過信道傳遞了過去stringstrMBRObj對象實例對象引用看起來似乎從服務器獲得了一個MBRObj類型的對象實例,其實獲得的只是這個實例的引用,實例實體只有一份,在服務器上??蛻舳藢Α癿br”變量任何方法的調用,都跟上述的obj一樣,將參數(shù)通過信道傳遞到服務器上去,方法代碼在服務器上執(zhí)行。31對象封送方式(續(xù))MBV:值封送當服務器端把MBV對象傳給客戶端時,客戶端所得到的是服務器端對象的一個完整副本這意味著:客戶端對所獲得的MBV對象任何方法/屬性的訪問,都是本地調用,不會影響到服務器上的對象使用“通信對象”的方法進行通信時,可使用MBV對象作為形參或返回值32MBV對象傳遞示意圖客戶端服務器端信道//MyObject是遠程對象類型MyObjectobj=newMyObject();MBVObjmbv=obj.GetObj();MyObject對象實例MBVObj對象實例MBVObj對象實例服務器上生成一個實例,并拷貝一份,通過信道傳遞給客戶端?!癿bv”已經是本地變量,客戶端對“mbv”變量任何方法的調用,都是在本地執(zhí)行,對服務器沒有影響。33對象封送方式(續(xù))什么樣的對象是MBR對象?派生自MarshalByRefObject的對象什么樣的對象是MBV對象?不派生自MarshalByRefObject,且可序列化的對象什么樣的對象可序列化?具有[Serizable]特性的對象,都是可序列化的,例如:[Serizable]publicclassMyObject{……}34MBR激活類型MBR對象的實體保存在服務器端那么這個對象什么時候實例化?先想一下本地對象是怎么實例化的當程序使用new關鍵字,或Activator.GetObject動態(tài)生成時,對象實例化MBR對象實例化的兩個思路:客戶端使用new關鍵字時,通過代理傳遞消息到服務器,對象實例化當對象真正被用到時(例如:首次調用其方法或屬性時),根據(jù)客戶端的消息,服務器端進行實例化如果選擇前者,則稱此MBR對象是“知名對象(WKO)”;選擇后者,則叫“客戶端激活對象(CAO)”35WKO激活示意圖客戶端服務器端信道//MyObject是遠程對象類型MyObjectobj=newMyObject();obj.xxxx();MyObject對象實例客戶端用new關鍵字時,服務器端并未實例化客戶端嘗試調用此實例的一個方法時,服務器端才對其實例化36CAO激活示意圖客戶端服務器端信道//MyObject是遠程對象類型MyObjectobj=newMyObject();obj.xxxx();MyObject對象實例客戶端用new關鍵字時,服務器端立即實例化37MBR激活類型(續(xù))WKO與CAO的區(qū)別CAO可以使用帶參數(shù)的構造函數(shù)WKO必須使用無參數(shù)的構造函數(shù)為什么?38WKO類型狀態(tài)配置MBR對象是在服務器端實例化的當不同的客戶端使用同一個服務器上的MBR對象時,是實例化一次還是多次?也就是說:多個客戶端訪問服務器上MBR對象時,他們訪問的是同一個實例,還是各自不同的實例?SingleTon和SingleCallSingleTon:只有一個實例SingleCall:對應于每個客戶端,分別生成不同的實例39Singleton示意圖(WKO)客戶端服務器端信道//MyObject是遠程對象類型MyObjectobj=newMyObject();obj.xxxx();MyObject對象實例客戶端調用遠程WKO對象方法時,服務器端實例化客戶端2信道//MyObject是遠程對象類型MyObjectobj=newMyObject();obj.xxxx();另一個客戶端調用此遠程WKO對象方法時,如果服務器端先前已經實例化,則仍使用該實例,而不生成新的實例40SingleCall示意圖(WKO)客戶端服務器端信道//MyObject是遠程對象類型MyObjectobj=newMyObject();obj.xxxx();MyObject對象實例客戶端調用遠程WKO對象方法時,服務器端實例化客戶端2信道//MyObject是遠程對象類型MyObjectobj=newMyObject();obj.xxxx();另一個客戶端調用此遠程WKO對象方法時,又生成一個新的實例。MyObject對象實例241WKO-SingleCall與CAO的區(qū)別WKO-SingleCall在首次被調用時實例化,CAO在客戶端實例化時實例化WKO-SingleCall只能使用無參的構造,CAO可以使用有參構造WKO-SingleCall針對每個客戶端,只有一個實例(一對一);而CAO在客戶端可以構造多個實例WKO-SingleCall是無狀態(tài)保持的,當其方法被調用后,立即進入垃圾收集;CAO則有狀態(tài)保持42遠程對象的生存期管理遠程對象什么時候應該被垃圾回收?MBV對象對于服務器、客戶端來說,MBV都是本地對象,因此不再被使用時即可垃圾回收MBR對象對象實體在服務器上,而非客戶端本地什么時候才能確定它“不再被使用”?43MBR對象的生存期管理WKO-SingleCall無狀態(tài)保持的,當其方法被調用后,立即進入垃圾收集WKO-SingleTon所有客戶端都使用同一個實例服務器端無法確認什么時候它才“不再被使用”CAO有狀態(tài)保持,因遠程使用,也無法判斷什么時候不再被使用(為什么?)對于WKO-SingleTon和CAO對象實例,服務器端采用“租約”的方式,確定何時進入垃圾回收44租約管理對于WKO-SingleTon和CAO,使用租約的方式管理對象實例的垃圾收集實例化時,給定一個生存期,例如40分鐘;每次其方法被調用時,生存期時間復位,即恢復到40分鐘;當上一次調用后,生存期倒計時;如果到0仍無后續(xù)調用,則垃圾收集。再來調用怎么辦?重新生成一個實例。45內容提要通信模型概述套接字通信編程面向對象的通信.NETRemoting基本原理.NETRemoting通信編程46.NETRemoting編程.NETRemoting編程的步驟:客戶端/服務器端注冊一個或多個信道;客戶端/服務器端注冊一個或多個通信對象,即服務器上可被遠程訪問的MBR對象;客戶端實例化并使用此對象(實質上是通過代理遠程調用)47第一步:注冊信道//服務器端staticvoidMain(string[]args){
//注冊一個信道
ChannelServices.RegisterChannel(new
IpcChannel("localhost:9090"),false);}//客戶端staticvoidMain(string[]args){ChannelServices.RegisterChannel(newIpcChannel(),false);}服務器端注冊一個IPC信道。也可以注冊成TCP/HTTP信道。注冊信道時需要指明服務地址和端口客戶端也注冊一個IPC信道。由于客戶端用于訪問服務器端,所以自身的地址和端口無需指明48第二步:注冊通信對象//服務器端staticvoidMain(string[]args){
//注冊一個信道
ChannelServices.RegisterChannel(new
IpcChannel("localhost:9090"),false);//注冊通信對象RemotingObjectRemotingConfiguration.RegisterWellKnownServiceType(typeof(RemotingObject),"rmObj",WellKnownObjectMode.Singleton);}這里將其注冊成了WKO,SingleTon。也可以注冊成CAO的。當客戶端不使用new進行實例化時,不必在客戶端執(zhí)行注冊有關RemotingObject類型的定義,詳見示例代碼49第三步:客戶端實例化并使用對象//客戶端staticvoidMain(string[]args){ChannelServices.RegisterChannel(newIpcChannel(),false);IRemotingObjectrmObj=Activator.GetObject(typeof(IRemotingObject),"ipc://localhost:9090/rmObj")asIRemotingObject;Console.WriteLine(rmObj.GetContextInfo());MBRObjectmbrObj=rmObj.GetMBRObj();Console.WriteLine(mbrObj.GetContextInfo());}有關IRemotingObject、MBRObject類型的定義,詳見示例代碼字符串所指示的,就是在服務器端注冊的信道地址和服務名稱50.NETRemoting的一些關鍵類ChannelServices負責注冊信道、查找信道信息等RemotingConfiguration負責注冊通信對象,及判斷是否遠程對象等MarshalByRefObjectMBR對象基類給出租約訪問接口(ILease)51ChannelServicesChannelServices.RegisterChannel方法注冊一個信道ChannelServices.RegisteredChannels屬性獲得所有已注冊信道的列表ChannelServices.GetChannel方法根據(jù)信道的名字,獲取一個信道用什么表示“信道”?實現(xiàn)了IChannel和其它相關接口的類型,如TcpChannel/IpcChannel等52RemotingConfigurationRemotingConfiguration.RegisterWellKnownServiceType方法在服務器端注冊一個WKO對象RemotingConfiguration.RegisterWellKnownClientType方法在客戶端注冊一個WKO對象客戶端也可以不執(zhí)行這項注冊,而直接用Activator.GetObject實例化(如示例代碼);但注冊后可以使用new關鍵字實例化53RemotingConfiguration(續(xù))RemotingConfiguration.RegisterActivatedServiceType方法在服務器端注冊一個CAO對象RemotingConfiguration.RegisterActivatedClientType方法在客戶端注冊一個CAO對象54RemotingConfiguration(續(xù))以下函數(shù)用于獲取已注冊的服務器端或客戶端類型RemotingConfiguration.GetRegisteredActivatedClientTypes
RemotingConfiguration.GetRegisteredActivatedServiceTypesRemotingConfiguration.GetRegisteredWellKnownClientTypesRemotingConfiguration.GetRegisteredWellKnownServiceTypes以下函數(shù)用于判斷一個類型的遠程屬性RemotingConfiguration.IsActivationAllowedRemotingConfiguration.IsRemotelyActivatedClientTypeRemotingConfiguration.IsWellKnownClientType55MarshalByRefObject以下兩個方法用于WKO-SingleCall和CAO對象的租約管理MarshalByRefObject.GetLifeServiceMarshalByRefObject.InitializeLifeService有關租約管理的細節(jié)知識,請自行學習56.NETRemoting服務器端的宿主前述示例中,都是以一個控制臺進程作為宿主的。當此進程退出,服務器自然關閉實際應用中,理想的宿主是Windows服務程序這些程序不依賴用戶登錄,開機后即運行如果使用HTTP信道,則IIS也可以作為宿主此時,服務器的配置應寫在Web.config文件里當使用IIS作為宿主時,呈現(xiàn)出非常類似WebServices的特征57使用配置文件配置.NETRemoting前述示例,以編程(硬編碼)方式定義信道屬性、參數(shù)以及通信類型這樣做的不足在于:一旦需要調整這些參數(shù),則必須修改源碼重新編譯可以將信道和通信對象配置在配置文件中如果需要修改這些參數(shù),則修改配置文件即可58使用配置文件配置.NETRemoting服務器的示例(服務器端)<?xmlversion="1.0"encoding="utf-8"?><configuration><system.runtime.remoting><application><service>
<wellknownmode="Singleton"type="CSharpDemo.RemotingDemo.RemotingObject,RemotingServer"objectUri="rmObj"></wellknown></service><channels>
<channelref="ipc"portName="localhost:9090"></channel></channels></application></system.runtime.remoting></configuration>//服務器端staticvoidMain(st
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 課題申報參考:健全全過程人民民主制度體系研究
- 課題申報參考:家校社聯(lián)動共育模式對青少年24h活動行為與抑郁癥狀改善的促進研究
- 2025年香港離婚協(xié)議書范本離婚后子女監(jiān)護權協(xié)議3篇
- 二零二五年影視剪輯師版權合作協(xié)議3篇
- 二零二五版白酒銷售顧問銷售數(shù)據(jù)分析與報告合同3篇
- 二零二五版木材廠土地租賃合同與林業(yè)產業(yè)發(fā)展規(guī)劃3篇
- 二零二五版國際IT產品代理銷售協(xié)議2篇
- 2025版小區(qū)公共區(qū)域保潔與綠化維護承包合同3篇
- 2025年三明貨運從業(yè)資格證好考嗎
- 二零二五版供應鏈融資高額抵押反擔保合同3篇
- 2024公路瀝青路面結構內部狀況三維探地雷達快速檢測規(guī)程
- 2024年高考真題-地理(河北卷) 含答案
- 中國高血壓防治指南(2024年修訂版)解讀課件
- 2024風力發(fā)電葉片維保作業(yè)技術規(guī)范
- 《思想道德與法治》課程教學大綱
- 封條(標準A4打印封條)
- 運動技能學習與控制課件第十章動作技能的指導與示范
- 石油天然氣建設工程交工技術文件編制規(guī)范(SYT68822023年)交工技術文件表格儀表自動化安裝工程
- 中醫(yī)治療“濕疹”醫(yī)案72例
- 2023年大學生《思想道德與法治》考試題庫附答案(712題)
- 清代文學緒論
評論
0/150
提交評論