版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
第12章網(wǎng)絡(luò)編程內(nèi)容提要網(wǎng)絡(luò)編程概述互聯(lián)網(wǎng)傳輸協(xié)議
Socket上的讀寫操作
Unix域套接字套接字選項構(gòu)建并發(fā)服務(wù)器12.1網(wǎng)絡(luò)編程概述網(wǎng)絡(luò)套接字Socket
TCP/IP誕生于4.4BSD,隨著TCP/IP在互聯(lián)網(wǎng)的廣泛應(yīng)用,編程接口BSDsocket也事實上成為網(wǎng)絡(luò)接口標準。目前,已被包括Linux在內(nèi)的眾多操作系統(tǒng)支持。
BSDsocket為一種通用網(wǎng)絡(luò)編程接口,支持豐富的網(wǎng)絡(luò)協(xié)議,例如,ipx/spx等。系統(tǒng)調(diào)用接口層VFS接口層Socket抽象層EthernetTokenRingPPPSLIP網(wǎng)絡(luò)設(shè)備驅(qū)動接口層PF_INETPF_PACKETPF_IPXPF_UNIXiptcpudp設(shè)備驅(qū)動層協(xié)議層接口層SOCK_DGRAMSOCK_RAWSOCK_RAWSOCK_DGRAMSOCK_STREAMreadwriteclosesocketrecvsendLinux內(nèi)核支持的協(xié)議客戶機/服務(wù)器模型socket采用客戶機/服務(wù)器模式,服務(wù)器監(jiān)聽客戶機發(fā)送的連接請求,客戶機需預(yù)先獲知服務(wù)器的地址,雙方連接建立后,可實現(xiàn)雙向數(shù)據(jù)傳輸。
傳輸層通常提供兩種類型的傳輸服務(wù),面向連接的傳輸服務(wù)和無連接的傳輸服務(wù),對于面向連接的傳輸服務(wù),可確保雙方傳輸數(shù)據(jù)的有序和可靠。對于無連接的傳輸協(xié)議,無須建立連接,可直接根據(jù)對方地址收發(fā)數(shù)據(jù)。4TCP/IP協(xié)議TCP/IP作為互聯(lián)網(wǎng)的標準協(xié)議族,其傳輸層為上層提供TCP和UDP兩種服務(wù)。
TCP是一種面向連接的傳輸協(xié)議,通信雙方以字節(jié)流方式可靠地交換數(shù)據(jù),用戶無需關(guān)心內(nèi)部復(fù)雜的協(xié)商邏輯,但TCP也會消耗一定的帶寬資源。
UDP是一種無連接的數(shù)據(jù)報協(xié)議,以數(shù)據(jù)報為單位,數(shù)據(jù)報在傳輸過程中可能丟失和失序,UDP消耗相對較少的帶寬資源。應(yīng)用編程接口分類API功能描述socketAPIsocket創(chuàng)建套接字bind綁定地址listen監(jiān)聽綁定地址上的連接請求accept接收來自綁定地址上的連接請求connect向服務(wù)器發(fā)起連接請求recv/recvfrom/recvmsg接收數(shù)據(jù)send/sendto/sendmsg發(fā)送數(shù)據(jù)close/shutdown關(guān)閉/優(yōu)雅關(guān)閉sendfile在內(nèi)核空間傳輸文件socketpair創(chuàng)建互聯(lián)套接字getsockopt/setsockopt獲取/設(shè)置套接字選項12.2互聯(lián)網(wǎng)傳輸協(xié)議內(nèi)容提要面向連接的傳輸協(xié)議TCPsocket編程接口無連接的傳輸協(xié)議UDP面向連接的傳輸協(xié)議TCPTCP是一種面向連接基于字節(jié)流的可靠傳輸協(xié)議,確保通信雙方數(shù)據(jù)傳輸?shù)挠行蚝驼_。采用客戶機/服務(wù)器模式,服務(wù)器監(jiān)聽客戶機發(fā)起的連接請求,在雙方建立連接后,便可進行數(shù)據(jù)傳輸?;赥CP的客戶機/服務(wù)器模式服務(wù)器端請求數(shù)據(jù)socket()bind()listen()accept()socket()connect()send()recv()客戶端(Blockuntilconnection)建立連接recv()send()回復(fù)數(shù)據(jù)close()關(guān)閉連接recv()close()創(chuàng)建套接字1.socket函數(shù)頭文件
#include<sys/types.h> #include<sys/socket.h>函數(shù)原型
int
socket(intdomain,inttype,intprotocol);功能 創(chuàng)建套接字。參數(shù)
domain:協(xié)議族。
type:協(xié)議類型。
protocol:默認為0,通常用于原始套接字選項。返回值 成功:套接字的文件描述符,錯誤:返回-1。創(chuàng)建套接字(續(xù))參數(shù)domain描述AF_UNIX本地通信協(xié)議AF_INETIPv4互聯(lián)網(wǎng)協(xié)議AF_INET6IPv6互聯(lián)網(wǎng)協(xié)議AF_IPXIPXnovellprotocolsAF_NETLINK配置協(xié)議參數(shù)type描述SOCK_STREAM面向連接的字節(jié)流服務(wù)SOCK_DGRAM無連接不可靠數(shù)據(jù)報服務(wù)SOCK_RAW底層協(xié)議訪問服務(wù)socket函數(shù)中參數(shù)type的定義函數(shù)中參數(shù)domain的定義綁定地址頭文件
#include<sys/types.h> #include<sys/socket.h>函數(shù)原型
int
bind(int
sockfd,struct
sockaddr*addr,socklen_t
addrlen);功能 綁定本地地址。參數(shù)
sockfd:套接字的文件描述符。
addr:ip地址。
addrlen:地址長度。返回值 成功返回0,錯誤:返回-1。綁定地址(續(xù))sockaddr使用更一般的類型,其定義如下。
struct
sockaddr{
sa_family_t
sa_family;//協(xié)議族
charsa_data[14];//內(nèi)容與協(xié)議族有關(guān)
}TCP/IP協(xié)議族的地址類型有ipv4和ipv兩種,下面僅以ipv4未例,其地址類型sockaddr_in的定義如下。struct
sockaddr_in{shortint
sin_family;//取值為AF_INETunsignedshortint
sin_port;//端口號struct
in_addr
sin_addr;//IP地址...};監(jiān)聽套接字頭文件
#include<sys/socket.h>函數(shù)原型
int
listen(int
sockfd,intbacklog);功能 監(jiān)聽套接字上的連接請求。參數(shù)
sockfd:套接字的文件描述符。
backlog:可容納連接請求的數(shù)量。返回值 成功返回0,錯誤返回-1。接收連接頭文件
#include<sys/types.h> #include<sys/socket.h>函數(shù)原型
int
accept(int
sockfd,struct
sockaddr*addr,socklen_t*addrlen);功能 接收連接。參數(shù)
sockfd:套接字的文件描述符。
addr:連接請求的地址。
addrlen:地址長度。返回值 成功返回為新連接創(chuàng)建的套接字,失敗返回-1。發(fā)起連接請求頭文件
#include<sys/types.h> #include<sys/socket.h>函數(shù)原型
int
connect(int
sockfd,struct
sockaddr*addr,socklen_t
addrlen);功能 向服務(wù)器發(fā)起連接請求。參數(shù)
sockfd:套接字的文件描述符。
addr:服務(wù)器地址。
addrlen:地址長度。返回值 成功返回0,錯誤返回-1。接收數(shù)據(jù)頭文件
#include<sys/types.h> #include<sys/socket.h>函數(shù)原型
ssize_t
recv(int
sockfd,void*buf,size_t
len,intflags);
ssize_t
recvfrom(int
sockfd,void*buf,size_t
len,int
flags,struct
sockaddr*from,socklen_t*addrlen);
ssize_t
recvmsg(int
sockfd,struct
msghdr*msg,intflags);功能 從套接字接收數(shù)據(jù)。參數(shù)
sockfd:套接字的文件描述符。buff:緩沖區(qū)地址。
len:緩沖區(qū)大小。from:目標地址。addrlen:地址長度。
msg:接收請求地址。flags:選項。返回值 成功返回接收的字節(jié)數(shù),失敗返回-1。接收數(shù)據(jù)recv(sockfd,buf,len,flags);等價于:recvfrom(sockfd,buf,len,flags,NULL,NULL);。msg
為msghdr類型指針,可使函數(shù)參數(shù)最小化,msghdr類型封裝了接收數(shù)據(jù)所需的參數(shù),其定義如下。struct
msghdr{void*msg_name;//目標地址
socklen_t
msg_namelen;//目標地址長度
struct
iovec*msg_iov;//緩沖區(qū)
size_t
msg_iovlen;//緩沖區(qū)數(shù)量
void*msg_control;//附加數(shù)據(jù)地址
size_t
msg_controllen;//附加數(shù)據(jù)長度
int
msg_flags;//用于接收數(shù)據(jù)};發(fā)送數(shù)據(jù)頭文件 #include<sys/types.h> #include<sys/socket.h>函數(shù)原型
ssize_t
send(int
sockfd,constvoid*buf,size_t
len,intflags);
ssize_t
sendto(int
sockfd,constvoid*buf,size_t
len,int
flags,const
struct
sockaddr*to,socklen_t
addrlen);
ssize_t
sendmsg(int
sockfd,conststruct
msghdr*msg,intflags);功能
向套接字發(fā)送數(shù)據(jù)。參數(shù)
sockfd:套接字的文件描述符uff:緩沖區(qū)地址。
len:緩沖區(qū)大小。to:目標地址。addrlen:地址長度。
msg:發(fā)送請求。flags:選項。返回值 成功返回發(fā)送的字節(jié)數(shù),失敗返回-1。關(guān)閉連接頭文件
#include<unistd.h> #include<sys/socket.h>函數(shù)原型
int
close(int
sockfd);
int
shutdown(int
sockfd,inthow);功能 關(guān)閉/優(yōu)雅關(guān)閉連接。參數(shù)
sockfd:套接字的文件描述符。
how:關(guān)閉的方式。返回值 成功返回0,失敗返回-1。關(guān)閉連接
無須傳輸數(shù)據(jù)時,應(yīng)關(guān)閉連接,當向已關(guān)閉的套接字發(fā)送數(shù)據(jù)時,將導(dǎo)致失敗。當調(diào)用close函數(shù)關(guān)閉連接時,若套接字的內(nèi)核發(fā)送緩沖尚有未發(fā)送的數(shù)據(jù),close會一直等待,直至數(shù)據(jù)全部發(fā)送完成或超時。并非所有發(fā)生異常的一方都產(chǎn)生RST包,需通過其他手段獲知對方的狀態(tài)。優(yōu)雅關(guān)閉close函數(shù)會將收發(fā)兩條通道全部關(guān)閉,后續(xù)無法接收數(shù)據(jù);若使用shutdown函數(shù),可僅關(guān)閉寫通道,但仍可繼續(xù)接收數(shù)據(jù),故稱為優(yōu)雅關(guān)閉。收到FIN包的一方返回0,僅表示對方已關(guān)閉了寫操作,無法確定對方是否關(guān)閉了讀操作。無連接的傳輸協(xié)議UDPUDP為無連接的傳輸協(xié)議,無法保證將數(shù)據(jù)有序且正確地送達對方,但并不意味著丟報現(xiàn)象的頻繁發(fā)生,這取決于整個網(wǎng)絡(luò)的狀態(tài)。在局域網(wǎng)環(huán)境下,通常有很高的可靠性。相較于TCP,UDP消耗較少的帶寬資源,具有較高的傳輸效率。
UDP在很多應(yīng)用場景得到了廣泛應(yīng)用,例如,流媒體和網(wǎng)絡(luò)電話等。3基于UDP的客戶機/服務(wù)器模式請求數(shù)據(jù)socket()bind()recvfrom()服務(wù)器端socket()sendto()recvfrom()客戶機端(Blockuntilreceivedatagram)sendto()回復(fù)數(shù)據(jù)close()12.3Socket上的讀寫操作內(nèi)容提要socket支持文件I/O接口面向連接的I/O操作socket的異步驅(qū)動模式零拷貝技術(shù)字節(jié)序和字節(jié)對齊socket支持文件I/O接口
內(nèi)核為socket提供了文件I/O接口的支持,對于新建套接字時返回的套接字描述符,也適用于文件的I/O操作,例如,read/write函數(shù)和select/poll函數(shù)等。由于標準I/O函數(shù)庫建立在基本文件I/O基礎(chǔ)上,因此,標準I/O函數(shù)庫中的函數(shù)也適用于套接字,例如,fgets和fputs函數(shù)等,由于在用戶空間設(shè)置了緩沖區(qū),從而會給I/O讀寫操作帶來一定的影響。面向連接的I/O操作
由于面向連接套接字的字節(jié)流特性,數(shù)據(jù)的流速取決于雙方套接字內(nèi)核緩沖區(qū)滑動窗口狀態(tài)的變化,無論采用阻塞或非阻塞模式,在讀寫套接字時,未必能將指定大小的數(shù)據(jù)一次性操作成功。面向連接的讀操作
對于讀操作,造成無法一次性全部讀取所需數(shù)據(jù)的因素如下。1.所需的數(shù)據(jù)未全部到達內(nèi)核接收緩沖區(qū)。2.即使全部到達,在讀取過程也可能被信號中斷。面向連接的寫操作
對于寫操作,造成無法一次性全部寫入指定數(shù)據(jù)的因素如下。1.寫入過程被信號中斷。2.在非阻塞模式下,套接字的內(nèi)核發(fā)送緩沖區(qū)僅能容納部分待寫入的數(shù)據(jù)。一次性讀特定大小的數(shù)據(jù)ssize_t
readn(int
fd,void*buffer,size_tn){
ssize_t
numRead;
size_t
totRead; char*buf;
buf=buffer; for(totRead=0;totRead<n;){
numRead=read(fd,buf,n-totRead); if(numRead==0) returntotRead; if((numRead==-1)&&(errno==EINTR)) continue; else return-1;
totRead+=numRead;
buf+=numRead; } returntotRead;}一次性寫入特定大小的數(shù)據(jù)ssize_t
writen(int
fd,constvoid*buffer,size_tn){
ssize_t
numWritten;
size_t
totWritten; constchar*buf;
buf=buffer; for(totWritten=0;totWritten<n;){
numWritten=write(fd,buf,n-totWritten);if(numWritten<=0){ if(numWritten==-1&&errno==EINTR) continue; else return-1; }
totWritten+=numWritten;
buf+=numWritten; } returntotWritten;}socket的異步I/O模式
對處于非阻塞模式的套接字,為了獲知套接字狀態(tài)的變化,內(nèi)核提供了兩種異步I/O驅(qū)動模式。異步I/O事件驅(qū)動2.異步I/O信號驅(qū)動。異步I/O事件驅(qū)動
內(nèi)核將套接字狀態(tài)的改變抽象為I/O事件,例如,套接字上有新數(shù)據(jù)到達和發(fā)送緩沖區(qū)重新變得可用等,用戶可通過select/poll/epoll監(jiān)聽套接字狀態(tài)的變化,利用獲取的I/O事件判斷狀態(tài)改變的原因,從而進行相應(yīng)的處理,事件類型I/O事件I/O事件的描述readPOLLIN有數(shù)據(jù)到達readPOLLIN面向連接的請求到達readPOLLHUP對方關(guān)閉了連接readPOLLHUP向失效的套接字上寫數(shù)據(jù),同時發(fā)送SIGPIPE信號WritePOLLOUT發(fā)送緩沖區(qū)變得可用Read/WritePOLLIN|POLLOUT連接完成Read/WritePOLLERR發(fā)生了異步I/O錯誤Read/WritePOLLHUP對方關(guān)閉了一個方向上的通道ExceptionPOLLPRI緊急數(shù)據(jù)到達,同時發(fā)送SIGURG信號異步I/O信號驅(qū)動
若利用fcntl函數(shù)在套接字上設(shè)置了O_ASYNC標識,套接字則被設(shè)置為I/O信號驅(qū)動模式,當套接字的狀態(tài)發(fā)生改變,內(nèi)核會向指定的進程發(fā)送SIGIO信號或自定義的實時信號。當存在多個狀態(tài)發(fā)生改變的套接字,信號處理程序可根據(jù)信號來源加以區(qū)分。零拷貝技術(shù)
對于某些應(yīng)用,在數(shù)據(jù)傳輸時,需頻繁在用戶空間和內(nèi)核空間復(fù)制數(shù)據(jù),例如,web和ftp等。為了降低帶來的系統(tǒng)開銷,內(nèi)核引入了稱為零拷貝的技術(shù),直接在內(nèi)核完成數(shù)據(jù)復(fù)制,繞過了用戶緩沖區(qū),減少了數(shù)據(jù)拷貝次數(shù)。零拷貝接口函數(shù)sendfile函數(shù)頭文件
#include<sys/sendfile.h>函數(shù)原型
ssize_t
sendfile(int
out_fd,int
in_fd,off_t*offset,size_tcount);功能 在內(nèi)核空間傳輸文件。參數(shù)
out_fd:目標套接字的文件描述符。
in_fd:源文件描述符。
offset:偏移量。
count:數(shù)據(jù)的長度。返回值 成功返回實際拷貝的字節(jié)數(shù),失敗返回-1。字節(jié)序(1)小端模式小端模式是指將低字節(jié)存放在內(nèi)存的低地址處,例如,Intel80x86處理器采用該模式。(2)大端模式大端模式正好與小端模式相反,將高字節(jié)存放在內(nèi)存的低地址處,Motorola處理器采用這種模式,網(wǎng)絡(luò)字節(jié)序采用大端模式,字節(jié)序的存儲模式High-orderbyteLow-orderbyte高位16位/2字節(jié)
低位Low-orderbyteHigh-orderbyte地址增長的方向地址增長的方向AddressAAddressA+1小端模式大端模式AddressA+1AddressA字節(jié)對齊
理論上。任意類型的數(shù)據(jù)可存儲于內(nèi)存的任意位置,但出于效率等因素的考慮,某些處理器對數(shù)據(jù)的存儲地址有一定的要求,n字節(jié)對齊是指數(shù)據(jù)的存儲地址為n的整數(shù)倍,例如,對于IntelX86,簡單類型和結(jié)構(gòu)類型的存儲地址均為4的整數(shù)倍。12.4Unix域套接字Unix域概述Unix域是一種特殊的傳輸協(xié)議,用于本地進程間通信,支持面向連接和無連接兩種傳輸服務(wù)。在使用socket編寫服務(wù)器和庫戶籍時,僅協(xié)議族和地址類型有所不同。Unix域套接字1.創(chuàng)建Unix域套接字Unix_socket=socket(AF_UNIX,type,0);2.Unix域的地址struct
sockaddr_un{
sa_family_t
sun_family;//取值A(chǔ)F_UNIX charsun_path[108];//文件路徑};互聯(lián)套接字
為了便于本地關(guān)聯(lián)進程間通信,內(nèi)核引入了socketpair接口函數(shù)用于創(chuàng)建一對互聯(lián)套接字,通過它可實現(xiàn)父子進程或兩子進程間通信。相較于無名管道的單向數(shù)據(jù)傳輸互聯(lián)套接字可實現(xiàn)雙向數(shù)據(jù)傳輸。創(chuàng)建互聯(lián)套接字socketpair函數(shù)頭文件
#include<sys/socket.h>函數(shù)原型
int
socketpair(intdomain,inttype,intprotocol,intsv[2]););功能 創(chuàng)建一對互聯(lián)套接字。參數(shù)
domain:協(xié)議族。
type:協(xié)議類型。
protocol:子協(xié)議類型。
sv[2]:一對互聯(lián)套接字的文件描述符。返回值 成功返回0,失敗返回-1。12.5套接字選項套接字選項概述
每個套接字都有自身的行為屬性,它們決定了套接字在收發(fā)數(shù)據(jù)時的行為特征。為了滿足個性化需要,內(nèi)核引入了getsockopt/setsockopt接口函數(shù),用于獲取/設(shè)置套接字的選項,以便套接字的行為符合用戶的需求。獲取/設(shè)置套接字選項getsockopt/setsockopt函數(shù)頭文件
#include<sys/socket.h>函數(shù)原型
int
getsockopt(int
sockfd,int
level,int
optname,void*optval,socklen_t*optlen);
int
setsockopt(int
sockfd,int
level,int
optname,void*optval,socklen_t
optlen);功能 獲取/設(shè)置套接字選項。參數(shù)
sockfd:套接字的文件描述符。
Level:協(xié)議層類型。
optname:選項名稱。
optval:選項值。
optlen:optval占用的字節(jié)數(shù)。返回值 成功返回0,失敗返回-1。通用選項參數(shù)optname類型定義SO_BROADCASTBOOL允許/禁止發(fā)送廣播消息SO_DEBUGBOOL設(shè)置是否允許調(diào)試SO_DONTROUTEBOOL設(shè)置是否繞過正常的路由器SO_KEEPALIVEBOOL定時監(jiān)測連接是否處于活動狀態(tài)SO_LINGERLINGER關(guān)閉鏈接時的超時設(shè)置SO_OOBINLINEBOOL設(shè)置緊急數(shù)據(jù)放入普通數(shù)據(jù)流SO_RCVBUFint設(shè)置接收緩沖區(qū)的大小SO_REUSEADDRBOOL打開或關(guān)閉地址復(fù)用功能SO_RCVTIMEODWORD設(shè)置接收函數(shù)的超時時間(毫秒)SO_SNDBUFint設(shè)置發(fā)送緩沖區(qū)的大小
通用選項位于套接字接口層,是對各類協(xié)議接口的抽象,與特定的協(xié)議無關(guān),但并非通用選項適用于所有協(xié)議。LINGER選項
該選項用于定義關(guān)閉連接時的超時設(shè)置,選項值的類型定義如下。#including<sys/socket.h> structlinger{ intl_onoff;//0表示關(guān)閉,非0表示打開 intl_linger;//超時時間(秒)};LINGER選項(續(xù))若成員變量l_onoff置為0,內(nèi)核默認設(shè)置,該選項關(guān)閉,成員變量l_linger的值被忽略,close/shutdown立即返回,殘留在發(fā)送緩沖區(qū)的數(shù)據(jù)被丟棄。2.若成員變量l_onoff置為非0,l_linger設(shè)置超時時間,調(diào)用的close/shutdown函數(shù)掛起,直至內(nèi)核發(fā)送緩沖區(qū)的數(shù)據(jù)全部被對方確認或超時時間到期;若到期仍有未確認的數(shù)據(jù),則向
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 單位外墻綠化施工合同范例
- 出租車運營合同格式3篇
- 合同解除證明模板3篇
- 勞動合同解除與離職后的權(quán)益保障3篇
- 供應(yīng)商合同中的技術(shù)交流3篇
- 基地合法養(yǎng)殖合同范例
- 恒大綠洲合同范例
- 拿貨抵款合同范例
- 給員工補合同范例
- 武漢軟件工程職業(yè)學(xué)院《法律與社會》2023-2024學(xué)年第一學(xué)期期末試卷
- 湖南省住宅物業(yè)服務(wù)分項目分等級基準價標準[完整版]
- 北京市工作居住證續(xù)簽申請表
- 學(xué)生英語短劇劇本《丑小鴨》
- 積分會員管理系統(tǒng)excel表格模板
- 小學(xué)體育障礙跑教案
- 中國 黑龍江 哈爾濱日出日落時間表
- 二年級體質(zhì)健康數(shù)據(jù)
- 2019年上海市春考高考英語試卷(精校含答案)
- (完整版)小學(xué)五年級英語上冊用所給詞語的適當形式填空
- 數(shù)字切片掃描儀操作流程及注意事項
- 刑法學(xué)形成性考核冊參考答案
評論
0/150
提交評論