




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、XXXXX大學實驗報告二O 15 年 12 月 23 日課程名稱:網絡及其計算 實驗名稱:SOCKET編程實現C/ Server程序班級: 姓名: 指導教師評定: 簽名: 一、 實驗目的1掌握網絡應用程序的開發方法;2掌握Client/ Server結構軟件的設計與開發方法3掌握Socket機制的工作原理二、 實驗要求1使用VC+,利用套接字技術編寫一個簡單的通信程序。2分析調試程序,了解VC+的特點,套接字的特性3記錄調試分析的全過程,加深對套接字的理解三、 實驗預備知識1、客戶機/服務器模式在網絡中最常用的通信模式是客戶機/服務器模式(Client/Server模式或C/S模式)。服務器方
2、要先啟動,并監聽指定端口,等待客戶端的請求,根據客戶端的請求提供相應服務。2、基本套接字一般來說,要進行網絡通信,必須要在網絡的每一端都要建立一個套接字,兩個套接字之間是可以建立連接的,也是可以無連接的,并通過對套接字的“讀”、“寫”操作實現網絡通信功能。類似于文件的打開、讀、寫、關閉的方式。套接字有三種類型:數據流套接字(SOCK_STREAM):對應TCP協議。數據報套接字(SOCK_DGRAM):對應UDP協議。原始套接字(SOCK_RAW)。通過使用原始套接字,可以將網卡設為混雜模式。并且可以捕獲到的數據包不僅僅是單純的數據信息,而是包含有 IP頭、 TCP頭等信息頭的最原始的數據信息
3、,這些信息保留了它在網絡傳輸時的原貌,通過對這些在低層傳輸的原始信息的分析可以得到更多網絡的信息。一個完整的網間通信需要一個五元組來標識: (協議,本地地址,本地端口號,遠地地址,遠地端口號)3、基本套接字系統調用 為了更好地說明套接字編程原理,下面給出幾個基本套接字系統調用說明。 a 創建套接字socket() 應用程序在使用套接字前,首先必須擁有一個套接字,系統調用socket()向應用程序提供創建套接字的手段,其調用格式如下: SOCKET PASCAL FAR socket(int af, int type, int protocol); 參數af:指定通信發生的區域,UNIX系統支持
4、的地址族有:AF_UNIX、AF_INET、AF_NS等,而DOS、WINDOWS中僅支持AF_INET,它是互連網區域。參數type:描述要建立的套接字的類型。參數protocol:說明該套接字使用的特定協議,如果調用者不希望特別指定使用的協議,則置為0,使用默認的協議。根據這三個參數建立一個套接字,并將相應的資源分配給它,同時返回一個整型套接字號。socket()系統調用實際上指定了相關五元組中的“協議”這一元。 b 指定本地地址bind() 將本地主機地址和本地端口與所創建的套接字號聯系起來,其調用格式如下: int PASCAL FAR bind(SOCKET s, const str
5、uct sockaddr FAR * name, int namelen); 參數s:是由socket()調用返回的套接字描述符(套接字號)。參數name:是賦給套接字s的本地地址,其長度可變,結構隨通信域的不同而不同,TCP/IP協議使用的地址結構如下:struct sockaddr_in short sin_family; /*AF_INET*/ u_short sin_port; /*16位端口號,網絡字節順序*/ struct in_addr sin_addr; /*32位IP地址,網絡字節順序*/ char sin_zero8; /*保留*/ 網絡字節順序:不同的計算機存放多字節值的
6、順序不同,有的機器在起始地址先存放低位字節,有的先存高位字節。為保證數據的正確性,在網絡協議中須指定網絡字節順序。TCP/IP協議使用16位整數和32位整數的高價先存格式,它們均含在協議頭文件中。參數namelen:表明了name的長度。 如果沒有錯誤發生,bind()返回0。否則返回值SOCKET_ERROR。 c 建立套接字連接connect()與accept() connect()用于建立連接。無連接的套接字進程也可以調用connect(),這樣就不必每次都指定目的地址。而accept()用于使服務器等待來自某客戶進程的實際連接。 int PASCAL FAR connect(SOCKE
7、T s, const struct sockaddr FAR * name, int namelen); 參數s:是欲建立連接的本地套接字描述符。參數name:為指向對方套接字地址結構的指針。參數namelen:對方套接字地址結構長度。 如果沒有錯誤發生,connect()返回0。否則返回值SOCKET_ERROR。 SOCKET PASCAL FAR accept(SOCKET s, struct sockaddr FAR* addr, int FAR* addrlen); 參數s:為本地套接字描述符,在用做accept()調用的參數前應該先調用過listen()。addr :指向客戶方套接
8、字地址結構的指針,用來接收連接實體的地址。Addrlen:為客戶方套接字地址結構的長度。如果沒有錯誤發生,accept()返回一個SOCKET類型的值,表示接收到的套接字的描述符。否則返回值INVALID_SOCKET。 accept()用于面向連接服務器。參數addr和addrlen存放客戶方的地址信息。調用前,參數addr 指向一個初始值為空的地址結構,而addrlen 的初始值為0;調用accept()后,服務器等待從編號為s的套接字上接受客戶連接請求,而連接請求是由客戶方的connect()調用發出的。當有連接請求到達時,accept()調用將請求連接隊列上的第一個客戶方套接字地址及長
9、度放入addr 和addrlen,并創建一個與s有相同特性的新套接字號。新的套接字可用于處理服務器并發請求。 四個套接字系統調用,socket()、bind()、connect()、accept(),可以完成一個完全五元相關的建立。socket()指定五元組中的協議元。bind()指定五元組中的本地二元,即本地主機地址和端口號,其用法與是否面向連接有關:在服務器方,無論是否面向連接,均要調用bind();在客戶方,若采用面向連接,則可以不調用bind(),而通過connect()自動完成。若采用無連接,客戶方必須使用bind()以獲得一個唯一的地址。 d 監聽連接listen() 此調用用于面
10、向連接服務器,表明它愿意接收連接。listen()需在accept()之前調用,其調用格式如下: int PASCAL FAR listen(SOCKET s, int backlog); 參數s:標識一個本地已建立、尚未連接的套接字號,服務器愿意從它上面接收請求。Backlog:表示請求連接隊列的最大長度,用于限制排隊請求個數,目前允許的最大值為5。如果沒有錯誤發生,listen()返回0。否則它返回SOCKET_ERROR。 e 數據傳輸send()與recv() 當一個連接建立以后,就可以傳輸數據了。常用的系統調用有send()和recv()。 int PASCAL FAR send(S
11、OCKET s, const char FAR *buf, int len, int flags); 參數s:為已連接的本地套接字描述符。buf :指向存有發送數據的緩沖區的指針,其長度由len 指定。Flags:指定傳輸控制方式,如是否發送帶外數據等。如果沒有錯誤發生,send()返回總共發送的字節數。否則它返回SOCKET_ERROR。 int PASCAL FAR recv(SOCKET s, char FAR *buf, int len, int flags); 參數s:為已連接的套接字描述符。Buf:指向接收輸入數據緩沖區的指針,其長度由len 指定。Flags:指定傳輸控制方式,如
12、是否接收帶外數據等。如果沒有錯誤發生,recv()返回總共接收的字節數。如果連接被關閉,返回0。否則它返回SOCKET_ERROR。* Flags參數可以是0或者是以下的組合:MSG_DONTROUTE:不查找路由表。是send函數使用的標志,這個標志告訴IP協議,目的主機在本地網絡上面,沒有必要查找路由表。MSG_OOB:表示可以接收和發送帶外的數據。MSG_PEEK:是recv函數的使用標志,表示只是從系統緩沖區中讀取內容,而不清除系統緩沖區的內容。這樣下次讀的時候,仍然是一樣的內容。一般在有多個進程讀寫數據時可以使用這個標志。MSG_WAITAL:是recv函數的使用標志,表示等到所有的
13、信息到達時才返回。使用這個標志的時候recv會一直阻塞,直到指定的條件滿足,或者是發生了錯誤。 1)當讀到了指定的字節時,函數正常返回,返回值等于len。 2)當讀到了文件的結尾時,函數正常返回,返回值小于len。3)當操作發生錯誤時,返回-1,且設置錯誤為相應的錯誤號(errno)。f數據傳輸sendto()與recvfrom() Sendto()用于在無連接套接字上發送消息。Recvfrom()可以記錄發送者的地址,該地址與sendto所指定的地址結構完全相同。 int sendto(int sockfd,const void *msg,int len,unsigned int flags
14、,struct sockaddr *to,int tolen) int recvfrom(int sockfd,void *buf,int len,unsigned int flags,struct sockaddr * from,int *fromlen) sockfd: 表示套接字描述符。buf: 發送或接收的緩沖區。len: 緩沖區及大小。recvfrom負責從sockfd接收數據,如果from不是NULL,那么在from里面存儲了信息來源的情況,如果對信息的來源不感興趣,可以將from和fromlen設置為NULL。sendto負責向to發送信息,此時在to里面存儲了接收信息方的詳細信
15、息。g數據傳輸recvmsg()和sendmsg()recvmsg和sendmsg的功能類似于recvfrom和sendto,只不過將一些信息放入了一個結構中。 int recvmsg(int sockfd,struct msghdr *msg,int flags) int sendmsg(int sockfd,struct msghdr *msg,int flags) struct msghdr void *msg_name; int msg_namelen; struct iovec *msg_iov; int msg_iovlen; void *msg_control; int msg_
16、controllen; int msg_flags; struct iovec void *iov_base; /* 緩沖區開始的地址 */ size_t iov_len; /* 緩沖區的長度 */ msg_name和 msg_namelen當套接字是非面向連接時(UDP),它們存儲接收和發送方的地址信息。msg_name實際上是一個指向struct sockaddr的指針,msg_name是結構的長度。當套接字是面向連接時,這兩個值應設為NULL. msg_iov和msg_iovlen指出接受和發送的緩沖區內容。msg_iov是一個結構指針,msg_iovlen指出這個結構數組的大小。 ms
17、g_control和msg_controllen這兩個變量是用來接收和發送控制數據時的 msg_flags指定接受和發送的操作選項,和recv,send的選項一樣。h關閉套接字closesocket() 與Shutdown()closesocket()關閉套接字s,并釋放分配給該套接字的資源;如果s涉及一個打開的TCP連接,則該連接被釋放。closesocket()的調用格式如下: BOOL PASCAL FAR closesocket(SOCKET s); 參數s:待關閉的套接字描述符。如果沒有錯誤發生,closesocket()返回0。否則返回值SOCKET_ERROR。 int shut
18、down(int sockfd,int howto) TCP連接是雙向的(是可讀寫的),當我們使用close時,會把讀寫通道都關閉,有時侯我們希望只關閉一個方向,這個時候我們可以使用shutdown。針對不同的howto,系統回采取不同的關閉方式. howto=0這個時候系統會關閉讀通道,但是可以繼續寫。howto=1關閉寫通道,但是可以繼續讀。 howto=2關閉讀寫通道。i輸入/輸出多路復用select() select()調用用來檢測一個或多個套接字的狀態。對每一個套接字來說,這個調用可以請求讀、寫或錯誤狀態方面的信息。請求給定狀態的套接字集合由一個fd_set結構指示。在返回時,此結構
19、被更新,以反映那些滿足特定條件的套接字的子集,同時, select()調用返回滿足條件的套接字的數目,其調用格式如下: int PASCAL FAR select(int nfds, fd_set FAR * readfds, fd_set FAR * writefds, fd_set FAR * exceptfds, const struct timeval FAR * timeout); 參數nfds:指明被檢查的套接字描述符的值域,此變量一般被忽略。 參數readfds:指向要做讀檢測的套接字描述符集合的指針,調用者希望從中讀取數據。參數writefds:指向要做寫檢測的套接字描述符集合
20、的指針。Exceptfds:指向要檢測是否出錯的套接字描述符集合的指針。Timeout:指向select()函數等待的最大時間,如果設為NULL則為阻塞操作。select()返回包含在fd_set結構中已準備好的套接字描述符的總數目,或者是發生錯誤則返回SOCKET_ERROR。 4、數據轉換和網絡信息函數 a、字節順序轉換函數在網絡上面有著許多類型的機器,這些機器在表示數據的字節順序是不同的, 比如i386芯片是低字節在內存地址的低端,高字節在高端,而alpha芯片卻相反。 為了統一起來,有專門的字節順序轉換函數。 unsigned long int htonl(unsigned long
21、int hostlong) unsigned short int htons(unisgned short int hostshort) unsigned long int ntohl(unsigned long int netlong) unsigned short int ntohs(unsigned short int netshort) 在這四個轉換函數中,h 代表host, n 代表 network。s 代表short, l 代表long,第一個函數的意義是將本機器上的long數據轉化為網絡上的long, 其它幾個函數的意義類似。b、IP和域名的轉換在網絡上標志一臺機器可以用IP或者
22、是用域名,那么怎么進行轉換呢? struct hostent *gethostbyname(const char *hostname) struct hostent *gethostbyaddr(const char *addr,int len,int type) 在中有struct hostent的定義 struct hostent char *h_name; /* 主機的正式名稱 */ char *h_aliases; /* 主機的別名 */ int h_addrtype;/* 主機的地址類型 AF_INET*/ int h_length; /* 主機的地址長度 對于IP4 是4字節32位
23、*/ char *h_addr_list; /* 主機的IP地址列表 */ #define h_addr h_addr_list0 /* 主機的第一個IP地址*/ gethostbyname可以將機器名(如 )轉換為一個結構指針.在這個結構里面儲存了域名的信息 gethostbyaddr可以將一個32位的IP地址(C0A80001)轉換為結構指針. 這兩個函數失敗時返回NULL 且設置h_errno錯誤變量,調用h_strerror()可以得到詳細的出錯信息 c、字符串的IP和32位的IP轉換. 在網絡上面IP地址都用點分十進制數字表示(如:192.168.0.1),而在struct in_a
24、ddr結構中用的是32位的IP,為了轉換我們可以使用下面兩個函數:int inet_aton(const char *cp,struct in_addr *inp) char *inet_ntoa(struct in_addr in) 函數里面a代表ascii,n代表network。第一個函數表示將a.b.c.d的IP轉換為32位的IP,,存儲在 inp指針里面。第二個是將32位IP轉換為a.b.c.d的格式。 d、服務信息函數 在網絡程序里面我們有時候需要知道端口、IP和服務信息,這個時候可以使用以下幾個函數 int getsockname(int sockfd,struct sockadd
25、r *localaddr,int *addrlen) int getpeername(int sockfd,struct sockaddr *peeraddr, int *addrlen) struct servent *getservbyname(const char *servname,const char *protoname) struct servent *getservbyport(int port,const char *protoname) struct servent char *s_name; /* 正式服務名 */ char *s_aliases; /* 別名列表 */
26、int s_port; /* 端口號 */ char *s_proto; /* 使用的協議 */ 5、典型調用時序圖a. 面向連接的套接字的系統調用時序圖a. 無連接協議的套接字調用時序圖6、面向連接示例程序aVC+ Socket編程 簡單的Tcp/ip服務器#include <windows.h>#include <iostream.h>#include <winsock.h>#define NO_FLAGS_SET 0#define PORT (u_short) 44965#define MAXBUFLEN 256INT main(VOID) WSADA
27、TA Data; SOCKADDR_IN serverSockAddr; SOCKADDR_IN clientSockAddr; SOCKET serverSocket; SOCKET clientSocket; int addrLen=sizeof(SOCKADDR_IN); int status; int numrcv; char bufferMAXBUFLEN; /* initialize the Windows Socket DLL */ status=WSAStartup(MAKEWORD(1, 1), &Data);/*初始化Winsock DLL if (status !
28、= 0) cerr << "ERROR: WSAStartup unsuccessful" << endl; /* zero the sockaddr_in structure */ memset(&serverSockAddr, 0,sizeof(serverSockAddr); /* specify the port portion of the address */ serverSockAddr.sin_port=htons(PORT); /* specify the address family as Internet */ serv
29、erSockAddr.sin_family=AF_INET; /* specify that the address does not matter */*INADDR_ANY 的具體含義是,綁定到0.0.0.0。此時,對所有的地址都將是有效的serverSockAddr.sin_addr.s_addr=htonl(INADDR_ANY); /* create a socket */ serverSocket=socket(AF_INET, SOCK_STREAM, 0); if (serverSocket = INVALID_SOCKET) cerr << "ERROR
30、: socket unsuccessful" << endl; /* associate the socket with the address */ status=bind(serverSocket, (LPSOCKADDR) &serverSockAddr, sizeof(serverSockAddr); if (status = SOCKET_ERROR) cerr << "ERROR: bind unsuccessful" << endl; /* allow the socket to take connecti
31、ons */ status=listen(serverSocket, 1); if (status = SOCKET_ERROR) cerr << "ERROR: listen unsuccessful" << endl; /* accept the connection request when one is received */ clientSocket=accept(serverSocket, (LPSOCKADDR) &clientSockAddr, &addrLen); cout << "Got th
32、e connection." << endl; while(1) numrcv=recv(clientSocket, buffer, MAXBUFLEN, NO_FLAGS_SET); if (numrcv = 0) | (numrcv = SOCKET_ERROR) cout << "Connection terminated." << endl; status=closesocket(clientSocket); if (status = SOCKET_ERROR) cerr << "ERROR: cl
33、osesocket unsuccessful" << endl; status=WSACleanup(); if (status = SOCKET_ERROR) cerr << "ERROR: WSACleanup unsuccessful" << endl; return(1); cout << buffer << endl; /* while */bVC+ Socket編程 簡單的Tcp/ip客戶端#include <windows.h>#include <iostream.h>
34、;#include <winsock.h>#define NO_FLAGS_SET 0#define PORT (u_short) 44965#define DEST_IP_ADDR "192.168.10.158" /Server addressINT main(VOID) WSADATA Data; SOCKADDR_IN destSockAddr; SOCKET destSocket; unsigned long destAddr; int status; int numsnt; char *toSendtxt="Test String"
35、; /* initialize the Windows Socket DLL */ status=WSAStartup(MAKEWORD(1, 1), &Data); if (status != 0) cerr << "ERROR: WSAStartup unsuccessful" << endl; /* convert IP address into in_addr form */ destAddr=inet_addr(DEST_IP_ADDR); /* copy destAddr into sockaddr_in structure */
36、 memcpy(&destSockAddr.sin_addr, &destAddr, sizeof(destAddr); /* specify the port portion of the address */ destSockAddr.sin_port=htons(PORT); /* specify the address family as Internet */ destSockAddr.sin_family=AF_INET; /* create a socket */ destSocket=socket(AF_INET, SOCK_STREAM, 0); if (de
37、stSocket = INVALID_SOCKET) cerr << "ERROR: socket unsuccessful" << endl; status=WSACleanup(); if (status = SOCKET_ERROR) cerr << "ERROR: WSACleanup unsuccessful" << endl; return(1); cout << "Trying to connect to IP Address: " << DEST_
38、IP_ADDR << endl; /* connect to the server */ status=connect(destSocket, (LPSOCKADDR) &destSockAddr, sizeof(destSockAddr); if (status = SOCKET_ERROR) cerr << "ERROR: connect unsuccessful" << endl; status=closesocket(destSocket); if (status = SOCKET_ERROR) cerr <<
39、 "ERROR: closesocket unsuccessful" << endl; status=WSACleanup(); if (status = SOCKET_ERROR) cerr << "ERROR: WSACleanup unsuccessful" << endl; return(1); cout << "Connected." << endl; while(1) cout << "Sending." << endl
40、; numsnt=send(destSocket, toSendtxt, strlen(toSendtxt) + 1, NO_FLAGS_SET); if (numsnt != (int)strlen(toSendtxt) + 1) cout << "Connection terminated" << endl; status=closesocket(destSocket); if (status = SOCKET_ERROR) cerr << "ERROR: closesocket unsuccessful" <
41、;< endl; status=WSACleanup(); if (status = SOCKET_ERROR) cerr << "ERROR: WSACleanup unsuccessful" << endl; return(1); /* Wait before sending the message again */ Sleep(4800); /* while */四、 實驗內容1 讀懂上面的示例程序,在Visual C+環境下調試執行。操作步驟:打開VC+6.0建立兩個win32 Consule Application,分別為server
42、、client,將服務器和客戶端程序代碼分別添加到工程的Source Files中(即server.cpp和client.cpp),并在工程/設置/連接中的對象/庫模塊中添加ws2_32.lib(windows socket鏈接庫),或者在程序中加入一行代碼:#pragma comment(lib,"ws2_32.lib")。然后分別編譯,成功后,先執行server.exe,結果如圖所示:然后執行client.exe,結果如圖所示:此時服務器端程序結果:2 參照示例程序,改寫為的無連接網絡通信程序(DOS界面執行)。面向無連接的網絡通信程序使用基于UDP的協議,修改通信程序
43、代碼如下:Server程序:#include <windows.h>#include <iostream>#include <winsock.h>#define NO_FLAGS_SET 0#define PORT (u_short) 44965#define MAXBUFLEN 256INT main(VOID)WSADATA Data;SOCKADDR_IN serverSockAddr;SOCKET serverSocket;int addrLen=sizeof(serverSockAddr);int status;/* initialize the
44、Windows Socket DLL */status=WSAStartup(MAKEWORD(1, 1), &Data);/初始化Winsock DLLif (status != 0)cerr << "ERROR: WSAStartup unsuccessful" << endl;/* zero the sockaddr_in structure */memset(&serverSockAddr, 0,sizeof(serverSockAddr);/* specify the port portion of the address
45、*/serverSockAddr.sin_port=htons(PORT);/* specify the address family as Internet */serverSockAddr.sin_family=AF_INET;/ specify that the address does not matter */INADDR_ANY 的具體含義是,綁定到0.0.0.0。此時,對所有的地址都將是有效的serverSockAddr.sin_addr.s_addr=htonl(INADDR_ANY);/* create a socket */serverSocket=socket(AF_IN
46、ET, SOCK_DGRAM, 0);if (serverSocket = INVALID_SOCKET)cerr << "ERROR: socket unsuccessful" << endl;/* associate the socket with the address */status=bind(serverSocket, (LPSOCKADDR) &serverSockAddr,sizeof(serverSockAddr);status=bind(serverSocket, (sockaddr *)&serverSockAd
47、dr,sizeof(serverSockAddr);if (status = SOCKET_ERROR)cerr << "ERROR: bind unsuccessful" << endl;char recvData255;int ret=recvfrom(serverSocket,recvData,255,0,(sockaddr*)&serverSockAddr,&addrLen);if(ret>0)recvDataret=0x00;printf("接受到一個連接:%srn",inet_ntoa(serve
48、rSockAddr.sin_addr);printf(recvData);char*sendData="一個來自服務端的UDP數據包n"sendto(serverSocket,sendData,strlen(sendData),0,(sockaddr*)&serverSockAddr,addrLen);status=closesocket(serverSocket);if (status = SOCKET_ERROR)cerr << "ERROR: closesocket unsuccessful"<< endl;stat
49、us=WSACleanup();if (status = SOCKET_ERROR)cerr << "ERROR: WSACleanup unsuccessful"<< endl;return 0;Client程序:#include <windows.h>#include <iostream>#include <winsock.h>#define NO_FLAGS_SET 0#define PORT (u_short) 44965#define DEST_IP_ADDR "192.168.0.103" /Server addressINT main(VOID)WSADATA Data;SOCKADDR_IN destSockAddr;SOCKET destSocket;unsigned long destAddr;int st
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 設備維修說明
- 青海省西寧市2025屆九年級下學期中考二模地理試卷(含答案)
- 自動控制原理第五版 胡壽松課后習題答案
- 貴州省黔東南州2023-2024學年八年級下學期期末考試語文試卷(含答案)
- 財務會計人員崗位職責
- 打造獨具特色的文旅商品品牌之路
- 道德與法治(河北卷)(考試版A3)
- 建筑施工特種作業-建筑電工真題庫-5
- 森林防火管護題目及答案
- 掃盲運動題目及答案高中
- 設計質量管理和保證措施及設計質量管理和質量保證措施
- 國家級社會體育指導員理論考試試題及答案
- 小學科學學法指導
- 充電樁建設項目可行性研究報告
- 第七屆全國急救技能大賽(醫生組)理論考試題庫大全-下部分
- 分級護理制度培訓
- 初中物理核心素養培養
- 安全應急管理培訓
- 寰樞關節錯位
- 公司股權投資管理制度
- 【低保政策執行過程中產生的消極效果及優化建議分析11000字(論文)】
評論
0/150
提交評論