




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、2020年12月3日星期四,1,上节课回顾,1、UNIX套接字编程接口 2、套接字编程接口编程 面向连接:不对等 面向无连接:对等 3、阻塞的概念及阻塞的解决办法,2020年12月3日星期四,2,上节课回顾,Send,Recv,2020年12月3日星期四,3,无连接的对等模式,上节课回顾,2020年12月3日星期四,4,关于阻塞的问题,服务器进程因调用ACCEPT()而被阻塞,上节课回顾,当套接字过程一直处于等待时,该过程就被阻塞,第三章 Windows环境的网络编程,1、WinSock API及与Unix Socket的区别和联系 2、WinSock API编程实例(VC6.0 版本),20
2、20年12月3日星期四,6,3.1 Windows Sockets规范,Winsock是一套开放的、支持多协议的Windows下的网络编程接口,应用程序通过调用Winsock API实现相互间的通信,而WinSock 利用下层的通信协议功能和操作系统调用实现实际的通信工作。 Winsock是比较底层的网络通信接口,现在VC环境已经对该接口进行了封装。但要实现更灵活的网络通信,必须在API层次上进行WinSock编程。,2020年12月3日星期四,7,3.1.1概述,图3.1 网络应用进程利用Windock进行通信,2020年12月3日星期四,8,3.1.2 Windows Sockets规范,
3、Windows Sockets 规范是一套开放的、支持多种协议的Windows下的网络编程接口。从1991年到1995年,从1.0版发展到2.0.8版,已成为Windows网络编程的事实上的标准。,2020年12月3日星期四,9,3.1.2 Windows Sockets规范,1Windows Sockets 1.1版本 包含两个文件: 库函数定义文件Winsock.h:定义了所有WinSock 1.1版本库函数的语法、相关的符号常量和数据结构。 库函数实现文件WINSOCK.DLL:库函数的实现。 注意: 第一个文件属于开发工具的一部分, 第二个文件属于操作系统的一部分。,2020年12月3
4、日星期四,10,3.1.2 Windows Sockets规范,WinSock 1.1 继承了Berkeley Sockets规范,主要函数,2020年12月3日星期四,11,3.1.2 Windows Sockets规范,其他辅助函数,2020年12月3日星期四,12,3.1.2 Windows Sockets规范,数据库函数(表3.2) 获取网络上的某些信息,需要网络上的数据库来实现。函数见表3.2,六个采用getXbyY()的形式。,2020年12月3日星期四,13,3.1.2 Windows Sockets规范,WinSock 1.1 扩充了Berkeley Sockets规范 P62
5、 WinSock 1.1定义了一批新的库函数(主要是异步操作函数,以WSA字符开头),提供对消息驱动机制的支持,有效利用Windows多任务多线程的机制。 两个函数需要注意: WSAStartUp:初始化Win Sockets DLL WSACleanUp:撤销Win Sockets DLL注册,2020年12月3日星期四,14,3.1.2 Windows Sockets规范,WinSock 1.1只支持TCP/IP协议栈 因此WinSock 1.1只支持Internet通信域,2020年12月3日星期四,15,3.1.2 Windows Sockets规范,2WinSock 2.0 WinS
6、ock 2.0与1.1兼容,同时增强了许多功能: 支持多种协议栈:增加了与底层协议栈的接口 引入了重叠I/O的概念:解决阻塞的问题 重叠I/O: 当进程再执行代码时产生一个I/O请求,操作系统会产生一个中断,让CPU去完成这个I/O请求,等到完成以后,系统再次产生一个操作完成通知。,2020年12月3日星期四,16,3.1.2 Windows Sockets规范,新功能: 使用事件对象异步通知:解决阻塞的问题 服务的质量(QOS): 基于连接:WSAConnect()函数的QOS参数设置服务质量 无连接: WSAConnect()函数可以为指定的通信规定特定的QOS级别 套接口组: 扩展的字节
7、顺序转换例程 分散/聚集方式I/O 新增了许多函数,2020年12月3日星期四,17,3.1.3 WinSock规范与Berkeley套接口的区别,1套接口数据类型和该类型的错误返回值 在WinSock中定义了一个新的数据类型SOCKET,用来代表套接字描述符。 typedef u_int SOCKET; 可以取从0到INVALID_SOCKET-1之间的任意值。 Socket() Acccept() 返回Socket类型。如果为错误,则为INVALID_SOCKET。,2020年12月3日星期四,18,2错误代码的获得 在UNIX 套接字规范中,如果函数执行时发生了错误,会把错误代码放到er
8、rno变量中。 在Winsock中,错误代码由WSAGetLastError()调用得到。(P72) 3指针(FAR 与 near) 所有应用程序与Windows Sockets使用的指针都必须是FAR指针.长指针数据类型LPHOSTENT= struct hostent FAR struct hostent FAR *lpHostEnt; lpHostEnt = gethostbyname (szHostName),3.1.3 WinSock规范与Berkeley套接口的区别,2020年12月3日星期四,19,4重命名的函数 close()改变为closesocket() ioctl()改变
9、为ioctlsocket() 5Winsock支持的最大套接口数目 在WINSOCK.H中缺省值是64,在编译时由常量FD_SETSIZE决定。 6头文件 WinSock应用程序只需包含WINSOCK.H。,3.1.3 WinSock规范与Berkeley套接口的区别,2020年12月3日星期四,20,3.1.3 WinSock规范与Berkeley套接口的区别,7Winsock规范对于消息驱动机制的支持 异步选择机制:WSAAsyncSelect()函数获取感兴趣的事件 异步请求函数:以异步方式获得请求信息 WSAAsyncGetXByY() 阻塞处理方法:利用钩子函数检测进程是否被阻塞,用
10、WSACallBlockingCall()取消阻塞 错误处理:WSAGetLastError() 启动和终止: WSAStartUp,WSACleanUp,3.2 Winsock 1.1的库函数,2020年12月3日星期四,22,3.2.1 Winsock的注册与注销,1初始化函数WSAStartup() Winsock 应用程序必须首先调用WSAStartup( )函数对Winsock进行初始化。初始化也称为注册。注册成功后,才能调用其他的Winsock API函数。 WSAStartup()函数的调用格式 int WSAStartup( WORD wVersionRequested, LP
11、WSADATA lpWSAData );,2020年12月3日星期四,23,3.2.1 Winsock的注册与注销,WSAStartup()函数的初始化过程(图3.2) 查找Winsock.dll并加载入内存 检查Winsock是否可用(确认版本号,随操作系统不同而不同) 建立Winsock与应用程序的联系,分配资源,DLL内置引用计数加1 函数返回成功时,则在参数lpWSAData 中包含其支持的最高版本,2020年12月3日星期四,24,图3.2 在一台计算机中,使用同一Windock实现的多个网络应用程序,LoadLibrary(),2020年12月3日星期四,25,3.2.1 Wins
12、ock的注册与注销,WSADATA结构的定义 #define WSADESCRIPTION_LEN 256 #define WSASYS_STATUS_LEN 128 typedef struct WSAData WORDwVersion; WORDwHighVersion; charszDescriptionWSADESCRIPTION_LEN+1; charszSystemStatusWSASYS_STATUS_LEN+1; unsigned shortiMaxSockets; unsigned shortiMaxUdpDg; char *lpVendorInfo; WSADATA;,20
13、20年12月3日星期四,26,3.2.1 Winsock的注册与注销,初始化函数可能返回的错误代码 WSASYSNOTREADY:网络通信依赖的网络子系统没有准备好。 WSAVERNOTSUPPORTED:找不到所需的Winsock API相应的动态连接库。 WSAEINVAL:DLL不支持应用程序所需的Winsock版本。 WSAEINPROGRESS:正在执行一个阻塞的Winsock 1.1操作。 WSAEPROCLIM:已经达到Winsock支持的任务数上限。 WSAEFAULT:参数lpWSAData不是合法指针。,2020年12月3日星期四,27,3.2.1 Winsock的注册与注
14、销,初始化Winsock的示例 #include aa() WORD wVersionRequested; /程序所需的Winsock版本号 WSADATA wsaData; / 返回Winsock 实现的细节信息 Int err; / 出错代码 wVersionRequested =MAKEWORD(1,1); / 生成版本号,2020年12月3日星期四,28,3.2.1 Winsock的注册与注销,/ 调用初始化函数。 err = WSAStartup(wVersionRequested, /* 至此,可以确认初始化成功,Winsock.DLL可用。 ,2020年12月3日星期四,29,3
15、.2.1 Winsock的注册与注销,几个VC函数说明 1、Makeword()函数 将两个byte型合并成一个word型,不是相加,而是一个在高8位,一个在低8位 2、LOBYTE() 取得双字节中最低(最右边)字节的内容 3、HIBYTE() 取得双字节中最高(最左边)字节的内容,2020年12月3日星期四,30,3.2.1 Winsock的注册与注销,2注销函数WSACleanup( ) 程序使用完Winsock.DLL提供的服务后,应用程序必须调用WSACleanup()函数: 解除与Winsock.DLL库的绑定 内置引用计数减1 释放Winsock分配给应用程序的系统资源 中止对W
16、indows Sockets DLL的使用 int WSACleanup ( void );,2020年12月3日星期四,31,3.2.2 Winsock的错误处理函数,1WSAGetLastError()函数 形式:int WSAGetLastError ( void ) 返回本线程进行的上一次Winsock函数调用时的错误代码。 2WSASetLastError()函数 形式:void WSASetLastError ( int iError ) 允许应用程序为当前线程设置错误代码,并可由后来的WSAGetLastError()调用返回。,2020年12月3日星期四,32,3.2.2 Wi
17、nsock的错误处理函数,3、错误代码列表:P72-P74 自定义函数实现错误提示: Void ShowError() int err; err=WSAGetLastError(); case err WSANOTINITIAISED: print(“没有注册DLL”); WSAENDDOWN: print(“网络子系统已经失效”); ,2020年12月3日星期四,33,3.2.3 主要的Winsock函数,1、创建套接口SOCKET() 形式: SOCKET socket ( int af, int type, int protocol); 举例: /* 创建一个流式套接字。 SOCKET
18、sockfd=SOCKET( AF_INET, SOCK_STREAM, 0); /* 创建一个数据报套接字。 SOCKET sockfd=SOCKET( AF_INET, SOCK_DGRAM, 0);,2020年12月3日星期四,34,3.2.3 主要的Winsock函数,2将套接口绑定到指定的网络地址BIND( ) int bind( SOCKET s, const struct sockaddr * name, int namelen); 相关的三种Winsock地址结构 有许多函数都需要套接字的地址信息,Winsock也定义了三种关于地址的结构,经常使用。,2020年12月3日星期四
19、,35,3.2.3 主要的Winsock函数,通用的Winsock地址结构,针对各种通信域的套接字,存储它们的地址信息。 struct sockaddr u_short sa_family; /* 地址家族 char sa_data14; /* 协议地址 ,2020年12月3日星期四,36,3.2.3 主要的Winsock函数,专门针对Internet 通信域的Winsock地址结构 struct sockaddr_in short sin_family; /* 指定地址家族,AF_INET. u_short sin_port; /* 指定分配给套接字层端口号, struct in_addr
20、sin_addr; /* 指定套接字的主机的IP char sin_zero8; /* 全置为0,是一个填充数。 ,2020年12月3日星期四,37,3.2.3 主要的Winsock函数,专用于存储IP地址的结构 Struct in_addr Union Struct u_char s_b1,s_b2,s_b3,s_b4; S_un_b; Struct u_short s_w1,s_w2; S_un_w; U_long S_addr; Union(联合)使用了内存覆盖技术。,2020年12月3日星期四,38,3.2.3 主要的Winsock函数,in_addr中是一个union,意思是这个结构
21、的大小为4个字节,可以用3种方法来访问: 当作一个u_long S_addr 当作2个u_short S_un_w.s_w1 S_un_w.s_w2 或4个u_char S_un_b.s_b1 S_un_b.s_b2 S_un_b.s_b3 S_un_b.s_b4,2020年12月3日星期四,39,3.2.3 主要的Winsock函数,在使用Internet 域的套接字时,这三个数据结构的一般用法是: 定义一个Sockaddr_in 的结构实例变量,并将它清零; 为这个结构的各成员变量赋值; 在调用BIND()绑定函数时,将指向这个结构的指针强制转换为 sockaddr*类型。,2020年12
22、月3日星期四,40,3.2.3 主要的Winsock函数,举例: SOCKET serSock; sockaddr_in my_addr; int err; int slen=sizeof( sockaddr); serSock = SOCKET(AF_INET, SOCK_DGRAM,0 ); memset(my_addr,0); my_addr.sin_family = AF_INET; my_addr.sin_port = htons(21);,2020年12月3日星期四,41,3.2.3 主要的Winsock函数,my_addr.sin_addr.s_addr = inet_addr(
23、202.193.96.32); 或者: my_addr.sin_addr.S_un_b.s_b1=202 my_addr.sin_addr.S_un_b.s_b2=193 my_addr.sin_addr.S_un_b.s_b3=96 my_addr.sin_addr.S_un_b.s_b4=32 if (BIND(serSock, (LPSOCKADDR ) ,2020年12月3日星期四,42,3.2.3 主要的Winsock函数,3启动服务器监听LISTEN()服务器端 格式:int listen( SOCKET s, int backlog); 功能:侦听客户端的连接,正确返回0 错误代
24、码: WSAGetLastError()函数处理 Listen(Sock,5); Err=WSAGetLastError(); Case Err ,2020年12月3日星期四,43,3.2.3 主要的Winsock函数,4接收连接请求ACCEPT( )服务器端 格式:SOCKET accept( SOCKET s, struct sockaddr* addr, int* addrlen); 功能:接收连接请求,正确则建立套接字 错误代码: WSAGetLastError()函数处理 Accept(Sock, addr,sizeof(addr ); Err=WSAGetLastError();
25、Case Err ,2020年12月3日星期四,44,3.2.3 主要的Winsock函数,5请求连接CONNECT()客户端 格式:int connect( SOCKET s, struct sockaddr * name, int namelen); 功能:连接服务器,正确返回0 错误代码: WSAGetLastError()函数处理 Connect(Sock, addr,sizeof(addr ); Err=WSAGetLastError(); Case Err ,2020年12月3日星期四,45,3.2.3 主要的Winsock函数,举例 structsockaddr_indaddr;
26、 memset(void*),2020年12月3日星期四,46,3.2.3 主要的Winsock函数,6、发送数据Send 形式:int send( SOCKET s, char* buf, int len, int flags); 功能:向对方发送数据,正确则返回实际发送的字节数 错误代码: WSAGetLastError()函数处理,2020年12月3日星期四,47,3.2.3 主要的Winsock函数,注意: 如果是数据报套接字,则发送的数据大小不能超过通信子网的最大IP包长度; 数据报的包最大长度在WSAStartUp( )函数返回,值为 iMaxUdpDg; 下层缓冲区空间不够保存需
27、要发送的数据,则Send函数可能阻塞;,2020年12月3日星期四,48,阻塞,错误,阻塞,2020年12月3日星期四,49,7从一个已连接套接口接收数据RECV(),int recv( SOCKET s, char * buf, int len, int flags); 图3-4说明了send和recv的作用,套接字缓冲区与应用进程缓冲区的关系,以及协议栈所作的传送。,图3.4 Send()和Recv()都是对本地套接字的操作,2020年12月3日星期四,50,3.2.3 主要的Winsock函数,8按照指定目的地向数据报套接字发送数据SENDTO() int sendto( SOCKET
28、s, char * buf, int len, int flags, struct sockaddr * to, int tolen); 9接收一个数据报并保存源地址,从数据报套接字接收数据RECVFORM() int recvfrom( SOCKET s, char * buf, int len, int flags, struct sockaddr* from, int* fromlen); 10关闭套接字CLOSESOCKET() int closesocket( SOCKET s); 11禁止在一个套接口上进行数据的接收与发送SHUTDOWN() int shutdown( SOCKE
29、T s, int how);,2020年12月3日星期四,51,3.2.4 Winsock的辅助函数,1Winsock中的字节顺序转换函数,图3-5 两种本机字节顺序,2020年12月3日星期四,52,3.2.4 Winsock的辅助函数,Winsock API特为此设置了四个函数: ()、htonl() 函数 功能:将主机的无符号长整型数本机顺序转换为网络字节顺序 ,用于IP地址。 形式:u_long PASCAL FAR htonl( u_long hostlong); hostlong:主机字节顺序表达的32位数。 htonl()返回一个网络字节顺序的值。,2020年12月3日星期四,5
30、3,3.2.4 Winsock的辅助函数,()、htons( )函数 功能:将主机的无符号短整型数转换成网络字节顺序,用于端口号。 形式:u_short PASCAL FAR htons( u_short hostshort); hostshort:主机字节顺序表达的16位数 htons()返回一个网络字节顺序的值,2020年12月3日星期四,54,3.2.4 Winsock的辅助函数,()、ntohl( )函数 功能:将一个无符号长整型数从网络字节顺序转换为主机字节顺序,用于IP地址。 形式:u_long PASCAL FAR ntohl( u_long netlong); Netlong:
31、是一个以网络字节顺序表达的32位数 ntohl()返回一个以主机字节顺序表达的数,2020年12月3日星期四,55,3.2.4 Winsock的辅助函数,()、ntohs( )函数 功能:将一个无符号短整型数从网络字节顺序转换为主机字节顺序,用于端口号。 形式:u_short PASCAL FAR ntohs( u_short netshort); netshort:是一个以网络字节顺序表达的16位数 ntohs( )返回一个以主机字节顺序表达的数,2020年12月3日星期四,56,3.2.4 Winsock的辅助函数,2获取与套接口相连的端地址GETPEERNAME() int getpee
32、rname( SOCKET s, struct sockaddr * name, int * namelen); 3获取一个套接口的本地名字GETSOCKNAME() int getsockname( SOCKET s, struct sockaddr * name, int * namelen); 4将一个点分十进制形式的IP地址转换成一个长整型数INET_ADDR() unsigned long inet_addr (const char * cp); 5将网络地址转换成点分十进制的字符串格式INET_NTOA() char * inet_ntoa( struct in_addr in);
33、,2020年12月3日星期四,57,3.2.5 Winsock的信息查询函数,Winsock API提供了一组信息查询函数,让我们能方便地获取套接口所需要的网络地址信息以及其它信息, 、Gethostname() 用来返回本地计算机的标准主机名。 int gethostname(char* name, int namelen); 、Gethostbyname() 返回对应于给定主机名的主机信息。 struct hostent* gethostbyname(const char* name);,2020年12月3日星期四,58,3.2.5 Winsock的信息查询函数,、Gethostbyadd
34、r() 根据一个IP地址取回相应的主机信息。 struct hostent* gethostbyaddr(const char* addr, int len, int type); 、Getservbyname() 返回对应于给定服务名和协议名的相关服务信息。 struct servent* getservbyname(const char* name, const char* proto); 、Getservbyport() 返回对应于给定端口号和协议名的相关服务信息。 struct servent * getservbyport(int port,const char *proto);,2
35、020年12月3日星期四,59,3.2.5 Winsock的信息查询函数,、Getprotobyname() 返回对应于给定协议名的相关协议信息。 struct protoent * getprotobyname(const char * name); 、Getprotobynumber() 返回对应于给定协议号的相关协议信息。 struct protoent * getprotobynumber(int number);,2020年12月3日星期四,60,3.2.5 Winsock的信息查询函数,除了Gethostname()函数以外,其它六个函数有以下共同的特点: 函数名都采用GetXby
36、Y的形式。 如果函数成功地执行,就返回一个指向某种结构的指针,该结构包含所需要的信息。 如果函数执行发生错误,就返回一个空指针。应用程序可以立即调用WSAGetLastError()来得到一个特定的错误代码。,2020年12月3日星期四,61,3.2.5 Winsock的信息查询函数,函数执行时,可能在本地计算机上查询,也可能通过网络向域名服务器发送请求。 Winsock API扩充了一组作用相同的异步查询函数。在每个函数名前面加上了WSAAsync前缀,采用WSAAsyncGetXByY()的形式。,2020年12月3日星期四,62,3.2.6 WSAAsyncGetXByY类型的扩展函数,
37、WSAAsyncGetXByY类型的扩展函数是 GetXByY函数的异步版本,这些函数可以很好地利用Windows的消息驱动机制。 1WSAAsyncGetHostByName()函数 HANDLE WSAAsyncGetHostByName ( HWND hWnd, unsigned int wMsg ,const char * name, char * buf, int buflen ); 2WSAAsyncGetHostByAddr()函数 HANDLE WSAAsyncGetHostByAddr ( HWND hWnd, unsigned int wMsg ,const char *
38、addr, int len, int type, char * buf, int buflen );,窗口句柄,2020年12月3日星期四,63,3.2.6 WSAAsyncGetXByY类型的扩展函数,3WSAAsyncGetServByName()函数 HANDLE WSAAsyncGetServByName ( HWND hWnd, unsigned int wMsg ,const char * name, const char * proto, char * buf, int buflen ); 4WSAAsyncGetServByPort() HANDLE WSAAsyncGetSe
39、rvByPort ( HWND hWnd, unsigned int wMsg, int port, const char * proto, char * buf, int buflen );,2020年12月3日星期四,64,3.2.6 WSAAsyncGetXByY类型的扩展函数,5WSAAsyncGetProtoByName()函数 HANDLE WSAAsyncGetProtoByName ( HWND hWnd, unsigned int wMsg, const char * name, char * buf, int buflen ); 6WSAAsyncGetProtoByNum
40、ber()函数 HANDLE WSAAsyncGetProtoByNumber ( HWND hWnd, unsigned int wMsg ,int number, char * buf, int buflen);,2020年12月3日星期四,65,3.3 网络应用程序的运行环境,1开发WinSocket应用程序的软、硬件环境 采用支持Windows Sockets API的Win 98SE以上的操作系统。 采用可视化和面向对象技术的编程语言,如VC 6.0 采用TCP/IP网络通信协议。,2020年12月3日星期四,66,3.3 网络应用程序的运行环境,网络中的所采用的计算机应满足Wind
41、ows 运行的配置要求。 网络中各节点上的计算机需安装网卡,并安装网卡的驱动程序。可以采用以太网交换机将若干台计算机组建成局域网。 在配置网络时,首先实现对等网,使各计算机节点能在“网上邻居”中找到自己和其它各计算机,并能实现文件资源相互共享。 其次,网络配置中,应添加TCP/IP协议,设定相应的IP地址。,2020年12月3日星期四,67,3.3 网络应用程序的运行环境,2调用Win Sockets接口的基本步骤 采用不同套接字的应用程序的调用套接字函数时,应遵循相应的步骤。 3程序开发的其它技术要点 首先做好初始化处理。 通信双方的程序应采用统一的界面形式。 尽量采用多线程编程技术。 应充分利用Win Sockets的基于消息的网络事件异步选择机制。,2020年12月3日星期四,68,3.1.2 Windows Sockets规范,3WinSock 1.1中的阻塞问题 在Berkeley 套接口模型中,一个套接口的操作的缺省行为是阻塞方式的。 在Windows环境下,程序员在尽可能的情况下使用非阻塞方式(异步方式)的操作。 Window环境下无法立刻完成的阻塞操作处理过程: P65 第二段 方法:循环中发送消息+WSACancelBlockingCall( ),2020年12月3日星期四,69,上
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年中考语文模拟试卷
- 2003年江苏省徐州市中考数学真题【含答案、解析】【含答案、解析】
- 考研复习-风景园林基础考研试题附参考答案详解【巩固】
- 考研复习-风景园林基础考研试题(培优b卷)附答案详解
- 风景园林基础考研资料试题及参考答案详解【b卷】
- 2025-2026年高校教师资格证之《高等教育法规》通关题库附答案详解(研优卷)
- 2025年K12课外辅导行业双减政策对行业培训机构的挑战与机遇报告
- 2024年消防条令纲要知识考试题库带答案(培优b卷)
- 2025年普通高等学校招生全国统一考试数学试题(全国一卷)(有解析)
- 食管静脉曲张出血的综合处理2025
- Unit 5 The Value of Money Reading for Writing 说课稿-2023-2024学年高中英语人教版(2019)必修第三册
- 《抑郁症护理查房》课件
- 2025神华新街能源限责任公司系统内招聘23人(第二批)高频重点提升(共500题)附带答案详解
- 仓库保管员测试题与答案
- 2025届湖北武汉市高考仿真模拟数学试卷含解析
- 子宫内膜息肉的治疗
- 人工智能赋能竞技体育数字化转型的作用机制、应用场景与实现路径
- 2024年云南高中学业水平合格考历史试卷真题(含答案详解)
- 马工程管理学自测题
- ICU镇痛镇静治疗护理
- 2024年心衰治疗指南解读
评论
0/150
提交评论