![文件传输协议的C语言实现_第1页](http://file3.renrendoc.com/fileroot_temp3/2022-2/21/a6a734b9-f832-4497-9059-86bb3208ff40/a6a734b9-f832-4497-9059-86bb3208ff401.gif)
![文件传输协议的C语言实现_第2页](http://file3.renrendoc.com/fileroot_temp3/2022-2/21/a6a734b9-f832-4497-9059-86bb3208ff40/a6a734b9-f832-4497-9059-86bb3208ff402.gif)
![文件传输协议的C语言实现_第3页](http://file3.renrendoc.com/fileroot_temp3/2022-2/21/a6a734b9-f832-4497-9059-86bb3208ff40/a6a734b9-f832-4497-9059-86bb3208ff403.gif)
![文件传输协议的C语言实现_第4页](http://file3.renrendoc.com/fileroot_temp3/2022-2/21/a6a734b9-f832-4497-9059-86bb3208ff40/a6a734b9-f832-4497-9059-86bb3208ff404.gif)
![文件传输协议的C语言实现_第5页](http://file3.renrendoc.com/fileroot_temp3/2022-2/21/a6a734b9-f832-4497-9059-86bb3208ff40/a6a734b9-f832-4497-9059-86bb3208ff405.gif)
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、第ChpNum章 文件传输协议的C语言实现1设计目的本设计旨在利用Winsock 2.0简单实现FTP(File Transfer Protocol,文件传输协议)的客户端和服务器端程序。通过完成此设计,了解Winsock API函数调用方法和一般网络应用程序的编程方法,理解FTP协议,掌握C语言设计FTP协议软件的基本技术,为将来开发其他通信协议软件打下坚实基础。 2 设计准备(1)连入同一局域网的PC,每人一台。(2)PC装有Windows操作系统、Visual C+ 6.0编译器及开发手册MSDN 6.0。3关键技术3.1 文件传输协议介绍FTP 是File Transfer Proto
2、col(文件传输协议)的英文简称,用于Internet上的控制文件的双向传输。在实现的层面上,FTP又可理解为一个可用于文件传输的客户机/服务器系统,该系统包括客户机端程序和服务器端程序,客户端和服务器端通信规则为FTP协议。用户通过客户机程序向服务器程序发出命令请求,服务器程序执行用户所发出的命令,并将执行的结果返回到客户机。比如说,用户发出一条命令,要求服务器向用户传送某一个文件的一份拷贝,服务器会响应这条命令,将指定文件送至用户的机器上。客户机程序接收到这个文件,将其存放在用户目录中。在通信协议的分层模型中,文件传输协议是在TCP(Transmission control Protoco
3、l,传输控制协议)之上的一个应用层协议,应用程序之间的通信需要用到传输层提供的字节流透明无误传输服务。Windows操作系统具有TCP/IP协议栈,应用程序可通过Winsock API函数的调用实现端到端透明数据链接的建立。3.2 Winsock API介绍 因特网(Internet)最初是基于Unix的,而Sockets(套接字)是Unix第一个支持TCP/IP协议栈的网络API,最早于1982年8月随4.2 BSD版Unix推出,常被称为Berkeley sockets(伯克利套接字)。Winsock(Windows Sockets API)是从Sockets移植过来的TCP/IP编程的低
4、级Windows API。Winsock分1.1版和2.x版,从Windows 98开始使用2.x版。Winsock与windows操作系统的关系如图ChpNum-1所示。操作系统实现了TCP/IP协议栈,(包括传输层协议TCP及UDP;网络层协议IP、ICMP及IGMP;链路层协议ARP和RAR),该模块的相关功能以动态链接库的形式被应用程序调用。操作系统接受网卡驱动程序的注册,网卡驱动程序本质上是一套控制网卡硬件收发报文的函数,也是以动态链接库的形式被调用。物理通信介质是指网卡驱动芯片及其外围电路,完成链路层数据帧的封装/解封、发送/接收等功能。图ChpNum1 Winsock与操作系统的
5、关系套接字可看作是不同主机间的进程进行双向通信的虚拟管道端点:网络中两台主机各自在自己机器上建立通信的端点-套接字,然后使用套接字进行数据通信。一个套接字包含五个基本元素:协议类型、本地IP地址、本地端口、远端IP地址和远端端口。在操作系统中,套接字是一种系统资源,应用程序使用时应向操作系统申请或注册,使用结束后应用程序应释放该该套接字。和其他系统资源一样,操作系统为套接字分配一个唯一的ID(在Windows中被称作句柄)。根据网络通信的特征,套接字分为三类:流套接字(SOCK_STREAM)、数据报套接字(SOCK_DGRAM)和原始套接字(SOCK_RAW)。流套接字是面向连接的,它提供双
6、向的、有序的、无差错、无重复并且无记录边界的数据流服务,适用于处理大量数据,提供可靠的服务。数据报套接字是无连接的,它支持双向的数据传输,具有开销小、数据传输效率高的特点,但不保证数据传输的可靠性、有序性和无重复性,适合少量数据传输、以及时间敏感的音/视频等多媒体数据传输。原始套接字(SOCK_RAW)可以用作对底层协议(如IP或ICM)的直接访问。Winsock网络应用程序利用API 函数(如accept、send、recv等函数)进行I/O操作时有阻塞和非阻塞两种模式。若要获取的资源还没有到达(如:接收缓冲区中没有数据提供给recv函数),在阻塞模式下,执行I/O操作的Winsock函数在
7、I/O操作完成前会一直等待下去,不会立即返回;而在非阻塞模式下,该函数不管I/O操作有没有完成都会立即返回,若未完成一般会返回错误码WSAWOULDBLOCK,意味着必须重新进行尝试。阻塞模式与非阻塞模式比较,从编程角度来说,前者更便于使用,但从程序运行的效率来说,由于阻塞调用后会使得所在的线程(如果是主线程那么就是整个程序)等待在该I/O操作上,因此后者效率更高。默认情况下,这些I/O操作工作于阻塞模式。在阻塞模式下使用Winsock 2的API库函数进行数据报套接字编程的过程如图ChpNum-2所示。在服务器端,先调用WSASartup函数进行初始化,初始化完成后调用Socket函数创建一
8、个Socket s,再调用bind函数将该套接字绑定到某个特定端口,接下来调用Listen函数启动监听并调用Accept函数接收客户连接,若客户连接请求未及时到达,则Accept函数处于阻塞状态。Accept函数为客户端的连接请求创建一个新的套接字S1,在以后的通信中,服务器利用套接字s1与客户端进行数据双向传输。通信结束时,服务器可以采用Closesocket函数释放套接字,并可调用WSAClearup释放Winsock DLL。客户机是连接的请求的发起者,在创建Socket之后直接通过调用Connect发起连接请求,成功后即可以利用该Socket进行双向通信了。下面对Winsock 2提供
9、的主要接口函数逐一进行介绍。 图ChpNum-2 基于TCP的网络应用程序(1)WSAStartup()函数和WSACleanup()函数由于Winsock 2提供的API服务是以动态链接库ws2_32.dll实现的,所以必须先调用WSAStartup() 函数对ws2_32.dll进行加载初始化,协商Winsock的版本支持,并分配必要的资源。在应用程序关闭套接字后,还应调用WSACleanup( )函数来终止和卸载动态链接库ws2_32.dll,释放资源。(2)socket()函数服务进程和客户进程在通信前必须创建各自的套接字,然后才能用相应的套接字进行发送、接收操作,实现数据的传输。服务
10、进程总是先于客户进程启动,服务进程和客户进程调用socket() 函数创建套接字。(3)bind( ) 函数当用socket( )创建套接字后,它便存在于一个名字空间(地址族)中,但并未赋名。bind ( )函数通过给一个未命名套接字分配一个本地名字(主机地址/端口号)来为套接字建立本地捆绑。客户端一般隐式地向操作系统请求一个随机的未使用过的临时端口号,跟自己的IP地址一起,与所创建的套接字建立联系,由于该临时端口号客户端程序事先是不确定的,因此不显式地使用绑定函数。(4)listen( )函数调用listen( )函数对服务器上套接字启动监听,即允许客户连接请求开始排队。(5)accept(
11、 )函数服务器设置监听工作方式后,通过调用 accept( ) 函数使套接字等待接受客户连接。如果已有连接请求到来,该函数会返回一个新的套接字描述符,它对应于已经接受的那个客户端连接。对于该客户机后续的所有操作,都应使用这个新套接字。至于原来那个监听套接字,它仍然用于接受其他客户机连接,继续处于监听模式。(6)connect( )函数客户端利用 connect( ) 函数和服务器建立一个端到端的连接。(7)closesocket( )函数网络通信任务完成后,利用本函数释放套接字占用的所有资源。4 软件设计 本设计客户端及服务器端均采用单线程实现,命令和数据的传输在同一个Socket链接上进行。
12、客户端支持DIR(远端文件夹查询)、GET(文件下载)、PUT(文件上传)、PWD(远端当前路径查询)、CD(远端当前路径设置)、MD(远端文件夹创建)、DEL(远端文件删除)等7个常用FTP命令。 用户命令格式为“命令字 路径名/文件名”,如下载当前目录下的test.txt文件,则用户在控制台界面输入的命令格式为“GET test.txt”。客户机和服务器的命令格式约定为“命令字$路径名/文件名”,即test.txt文件下载命令格式为“命令字$路径名/文件名”。图ChpNum-3 程序流程图ChpNum-3(a)示出了客户机的主程序流程,初始化Winsock后,用socket函数新建一个so
13、cket,填写入服务器的及IP地址及监听端口后,利用connnect函数连接到服务器后即提示用户输入ftp命令,程序阻塞在scanf函数。用户输入命令后,scanf函数返回,通过字符串比对函数strncmp识别命令,并调用相应的命令发送函数,若输入的是quit命令,客户端程序退出。命令处理函数主要工作有两个,一是构建命令字节流发送到服务器,二是与服务器交互该命令的后续执行数据,例如,对于get命令,该函数在发出get命令请求字节流后,要接收服务器下发的文件数据。各命令处理函数的实现请参见源代码。图ChpNum-3(b)示出了服务器端主程序流程,先初始化Winsock,建立Socket并绑定到监
14、听端口,启动监听,阻塞在Accept函数等待连接请求的到来,当连接请求到达,Accept函数为该请求创建新的Socket用于与对应的客户通信,而原来Socket继续处于监听状态。此后,主程序从新的Socket中读取命令,通过字串比较识别命令,若发现是quit命令,则关闭当前连接,准备接收下一个连接;若不是quit命令,则转移到相应的命令处理函数,处理完毕后继续在该Socket上读取命令并进行处理。各命令处理函数的设计请参看源代码。5程序代码5.1 服务器端程序文件/*文件名: server.c说明: 简单的ftp服务器端程序文件,包含main函数及get、put等命令处理函数。*/#inclu
15、de <stdio.h>#include <winsock2.h>#include <stdlib.h>#pragma comment(lib,"ws2_32.lib")WSADATA wsd;char SendBuffer80,RecvBuffer80;/发送缓冲区及接收缓冲区#define DEFAULT_LSTN_PORT 2416 /本地默认监听端口int n,bytes;SOCKET h_NewSocket; /accept函数产生的新socketstruct sockaddr_in RemoteAddr; char path8
16、0=""char strObject100=""int iSynError=1; int sdirfun(SOCKET h_NewSocket);int sgetfun(SOCKET h_NewSocket);int sputfun(SOCKET h_NewSocket);int spwdfun(SOCKET h_NewSocket);int scdfun(SOCKET h_NewSocket);int smdfun(SOCKET h_NewSocket);int sdelfun(SOCKET h_NewSocket);/*函数名:main说明: 主函数
17、输入参数: int argc 输入参数长度 char *argv输入参数,用于传入监听端口号*/int main(int argc, char *argv) struct sockaddr_in SLocalAddr; SOCKET h_Socket4Lstn; /欲用作监听的socket int addr_in_len;/地址长度 /初始化winsock if (WSAStartup(MAKEWORD(2,2), &wsd) != 0) WSACleanup(); printf("WSAStartup failedn"); memset(&SLocalAd
18、dr,0,sizeof(SLocalAddr); /创建socket h_Socket4Lstn = socket(PF_INET, SOCK_STREAM, 0); if (h_Socket4Lstn <0) printf("creating socket failedn"); SLocalAddr.sin_family = AF_INET; if(argc = 2) SLocalAddr.sin_port = htons(u_short)atoi(argv1); else SLocalAddr.sin_port = htons(DEFAULT_LSTN_PORT)
19、; SLocalAddr.sin_addr.s_addr = INADDR_ANY; /绑定socket if (bind(h_Socket4Lstn,(struct sockaddr *)(&SLocalAddr),sizeof(SLocalAddr) < 0) printf("Bind failed!n"); while (1) /主循环 listen(h_Socket4Lstn,3); /启动监听 addr_in_len = sizeof(RemoteAddr); /接受连接请求 h_NewSocket = accept( h_Socket4Lstn,
20、(struct sockaddr *) (&RemoteAddr) , &addr_in_len); if (h_NewSocket = INVALID_SOCKET) break;/出错退出 printf("%s is connected at port %d n",inet_ntoa(RemoteAddr.sin_addr), ntohs(SLocalAddr.sin_port); sprintf(SendBuffer,"200 Welcome rn"); /向客户端发送欢迎消息 bytes = send(h_NewSocket, S
21、endBuffer, strlen(SendBuffer), 0); sprintf(SendBuffer,"530 Log in rn"); bytes = send(h_NewSocket, SendBuffer, strlen(SendBuffer), 0); while (1) /接收客户端的命令并调用命令处理函数 n = 0; iSynError=1; while (1) bytes = recv(h_NewSocket, &RecvBuffern, 1, 0); if (bytes < 0) | (bytes = 0) break; if (Rec
22、vBuffern = '$') RecvBuffern = '0' break; if (RecvBuffern != 'r') n+; if (bytes < 0) | (bytes = 0) break; printf("The Server received: '%s' cmd from client n", RecvBuffer); /命令识别 /查看当前目录 if(strncmp(RecvBuffer,"dir",3)=0) sdirfun(h_NewSocket); /查询
23、当前目录路径 if(strncmp(RecvBuffer,"pwd",3)=0) spwdfun(h_NewSocket); /改变当前目录 if (strncmp(RecvBuffer,"cd",2)=0) scdfun(h_NewSocket); /文件下载 if (strncmp(RecvBuffer,"get",3)=0) sgetfun(h_NewSocket); /文件上传 if (strncmp(RecvBuffer,"put",3)=0) sputfun(h_NewSocket); /新建文件夹 i
24、f (strncmp(RecvBuffer,"md",2)=0) smdfun(h_NewSocket); /删除文件 if (strncmp(RecvBuffer,"del",3)=0) sdelfun(h_NewSocket); if (strncmp(RecvBuffer,"quit",4)=0) /退出命令 printf("quit n"); sprintf(SendBuffer, "221 Bye bye . rn"); bytes = send(h_NewSocket, SendBu
25、ffer, strlen(SendBuffer), 0); iSynError=0; break; if (iSynError=1) /Syntax error printf("command unrecognized, non-implemented!n"); sprintf(SendBuffer, "500 Syntax error. n"); bytes = send(h_NewSocket, SendBuffer, strlen(SendBuffer), 0); closesocket(h_NewSocket); printf("%s
26、disconnected from port %d, control socket is closed.n", inet_ntoa(RemoteAddr.sin_addr),ntohs(SLocalAddr.sin_port); closesocket(h_Socket4Lstn); /释放监听的socket return 0;/*函数名:sdirfun说明: 用于处理来自客户端的目录查询命令输入参数: SOCKET h_NewSocket,命令通过此socket接收到,可通过它响应命令。*/int sdirfun(SOCKET h_NewSocket) char temp_buff
27、er80; FILE *p_FiLeTemp; /整理本地dir命令 strObject0='0' strcat(strObject,"dir "); strcat(strObject,path); strcat(strObject," >tmp.txt"); system(strObject); /system函数执行shell命令 p_FiLeTemp=fopen("tmp.txt","r"); /打开执行结果文件,准备发送到客户端 sprintf(SendBuffer, "12
28、5 Transfering. rn"); bytes = send(h_NewSocket, SendBuffer, strlen(SendBuffer), 0); while (fgets(temp_buffer,80,p_FiLeTemp)!=NULL) /每次读取80字节发送 sprintf(SendBuffer,"%s",temp_buffer); / send(h_NewSocket, SendBuffer, strlen(SendBuffer), 0); fclose(p_FiLeTemp); /发送完毕,关闭结果临时文件 sprintf(SendBu
29、ffer, "226 Transfer completed. rn"); bytes = send(h_NewSocket, SendBuffer, strlen(SendBuffer), 0); system("del tmp.txt"); /删除结果临时文件 sprintf(SendBuffer,"226 Close the data socket. rn"); bytes = send(h_NewSocket, SendBuffer, strlen(SendBuffer), 0); printf("dir comman
30、d has been done! n"); iSynError=0; return 0;/*函数名:sgetfun说明: 用于处理来自客户端的文件下载命令输入参数: SOCKET h_NewSocket,命令通过此socket接收到,可通过它响应命令。*/int sgetfun(SOCKET h_NewSocket) int i=4,k=0; char FileName20,temp_buffer80;char *p_FileName=strObject; FILE *fp;printf("required file is: "); /打印文件名到屏幕while
31、(1) /提取文件名 bytes = recv(h_NewSocket, &RecvBufferi, 1, 0); printf("%c",RecvBufferi); if (bytes < 0) | (bytes = 0) break; FileNamek=RecvBufferi; if (RecvBufferi = '0') FileNamek = '0' break; if (RecvBufferi != 'r') i+; k+; printf("n"); /文件名打印结束 strObj
32、ect0='0' strcat(strObject,path); if(strlen(path)>0) trcat(strObject,""); strcat(strObject,FileName); /打开客户端欲下载的文件 if( (fp=fopen(p_FileName,"r") = NULL ) /未成功打开文件 sprintf(SendBuffer, "Sorry, cannot open %s. Please try again.rn", FileName); bytes = send(h_NewSo
33、cket, SendBuffer, strlen(SendBuffer), 0); sprintf(SendBuffer, "226 Transfer completed. rn"); bytes = send(h_NewSocket, SendBuffer, strlen(SendBuffer), 0); return 1; else printf("The file %s is found,ready to transfer.n",FileName); sprintf(SendBuffer, "125 Transfering. rn&quo
34、t;); bytes = send(h_NewSocket, SendBuffer, strlen(SendBuffer), 0); while (fgets(temp_buffer,80,fp)!=NULL) /循环读取文件并通过h_NewSocket发送到客户端 sprintf(SendBuffer,"%s",temp_buffer); send(h_NewSocket, SendBuffer, 80, 0); printf("."); /文件发送中,每发80个字节在屏幕打一个点号 fclose(fp); sprintf(SendBuffer, &q
35、uot;226 Transfer completed. rn"); bytes = send(h_NewSocket, SendBuffer, strlen(SendBuffer), 0); iSynError=0; printf("get command has been done! n"); return 0;/*函数名:sputfun说明: 用于处理来自客户端的文件上传命令*/int sputfun(SOCKET h_NewSocket) Printf(“篇幅所限,请读者完成。n”); iSynError=0; return 0;/*函数名:spwdfun说
36、明: 用于处理来自客户端的当前路径查询命令*/int spwdfun(SOCKET h_NewSocket) Printf(“篇幅所限,请读者完成。n”); iSynError=0; return 0;/*函数名:scdfun说明: 用于处理来自客户端的当前路径设置命令*/int scdfun(SOCKET h_NewSocket) Printf(“篇幅所限,请读者完成。n”); iSynError=0; return 0;/*函数名:smdfun说明: 用于处理来自客户端的当前文件夹新建命令*/int smdfun(SOCKET h_NewSocket) Printf(“篇幅所限,请读者完成
37、。n”); iSynError=0; return 0;/*函数名:sdelfun说明: 用于处理来自客户端的文件删除命令*/int sdelfun(SOCKET h_NewSocket) Printf(“篇幅所限,请读者完成。n”); iSynError=0; return 0;5.2 客户端程序文件/*文件名: client.c说明: 简单的ftp客户端程序文件,包含main函数及get、put等命令发送函数。*/#include <winsock2.h>#include <stdio.h>#include <stdlib.h>#pragma comme
38、nt(lib,"ws2_32.lib")#define DEFAULT_SERV_PORT 2416 /服务器的监听端口#define DEFAULT_BUFFER_SIZE 2048 /缓冲区长度char sz_ServIp128; / 服务器的IP地址char sz_Msg2Snd1024; / 发给服务器端的字符串int iPort = DEFAULT_SERV_PORT; / 服务器的监听端口BOOL b_IsSendOnly = FALSE; / 只发消息,不收消息int dirfun(SOCKET ); /"dir"命令处理函数int get
39、fun(SOCKET h_Socket4Cmd,char FileName40); /"get"命令处理函数int putfun(SOCKET h_Socket4Cmd,char FileName40); /"put"命令处理函数int pwdfun(SOCKET); /"pwd"命令处理函数int cdfun(SOCKET h_Socket4Cmd,char pathname40); /"cd"命令处理函数int mdfun(SOCKET h_Socket4Cmd,char DocName20); /"
40、md"命令处理函数int delfun(SOCKET h_Socket4Cmd,char name20); /"del"命令处理函数int helpfun(); /"help"命令处理函数/*函数名:main说明: 主函数输入参数: int argc 输入参数长度 char *argv输入参数字符型数组*/int main(int argc, char *argv) WSADATA wsd; SOCKET h_Socket4Cmd; char szBufferDEFAULT_BUFFER_SIZE; int ret; struct sockad
41、dr_in server; struct hostent *host = NULL; char CmdWords5,CmdWords240; argv1="-s:" strcpy(sz_ServIp, &argv13); if (WSAStartup(MAKEWORD(2,2), &wsd) != 0) /winsock初始化 printf("Failed to load Winsock library!n"); return 1; h_Socket4Cmd = socket(AF_INET, SOCK_STREAM,
42、IPPROTO_TCP); if (h_Socket4Cmd = INVALID_SOCKET) printf("creating socket failed, error_code : %dn", WSAGetLastError(); return 1; server.sin_family = AF_INET; server.sin_port = htons(iPort); server.sin_addr.s_addr = inet_addr(sz_ServIp); if (server.sin_addr.s_addr = INADDR_NONE) host = geth
43、ostbyname(sz_ServIp); if (host = NULL) printf("Unable to resolve server: %sn", sz_ServIp); return 1; CopyMemory(&server.sin_addr, host->h_addr_list0, host->h_length); if (connect(h_Socket4Cmd, (struct sockaddr *)&server, sizeof(server) = SOCKET_ERROR) /链接到服务器端 printf("co
44、nnecting to server failed,error_num: %dn", WSAGetLastError(); return 1; /接收服务器欢迎消息并打印到屏幕 ret = recv(h_Socket4Cmd, szBuffer, DEFAULT_BUFFER_SIZE, 0); if (ret = 0) return 0; else if (ret = SOCKET_ERROR) printf("recv function failed,error_num: %dn", WSAGetLastError(); return 0; szBufferr
45、et = '0' printf("%sn",szBuffer); if(ret<15) ret = recv(h_Socket4Cmd, szBuffer, DEFAULT_BUFFER_SIZE, 0); if (ret = 0) return 0; else if (ret = SOCKET_ERROR) return 0; szBufferret = '0' printf("%sn",szBuffer); helpfun(); /打印命令列表 while(1) puts("-"); prin
46、tf("ftp> "); scanf("%s", CmdWords); /输入命令扫描 /输入命令识别 if(strncmp(CmdWords,"dir",3)=0|strncmp(CmdWords,"DIR",3)=0) dirfun(h_Socket4Cmd); continue; else if(strncmp(CmdWords,"pwd",3)=0|strncmp(CmdWords,"PWD",3)=0) pwdfun(h_Socket4Cmd); continue; else if(strncmp(CmdWords,"?"
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年江苏货运资格证考试题库答案
- 小学二年级数学下学期竞赛口算题
- 2025年天津货运从业资格考试题目及答案大全解析
- 2025年黑龙江货运资格证考试70题
- 电力技术转让合同(2篇)
- 2024-2025学年八年级数学上册第六章数据的分析1平均数教案新版北师大版
- 2024年高中语文第一单元4碗花糕演练含解析粤教版选修4中国现代散文蚜
- 苏人版道德与法治九年级上册10.3《做一个成熟的消费者》听课评课记录
- 骨干教师研修总结
- 食品代工合同范本
- 4地球-我们的家园《我们共同的责任》说课稿 -2023-2024学年道德与法治六年级下册统编版
- 护理交接班改进
- (一模)芜湖市2024-2025学年度第一学期中学教学质量监控 英语试卷(含答案)
- 完整版秸秆炭化成型综合利用项目可行性研究报告
- 诗经楚辞文学常识单选题100道及答案
- AI辅助的慢性病监测与管理系统
- 2025年小学蛇年寒假特色作业
- 2025中国海油春季校园招聘1900人高频重点提升(共500题)附带答案详解
- 胆汁淤积性肝硬化护理
- Unit 6 Is he your grandpa 第一课时 (教学实录) -2024-2025学年译林版(三起)(2024)英语三年级上册
- 《数据采集技术》课件-Scrapy 框架的基本操作
评论
0/150
提交评论