




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、 成績(jī): 2015-2016學(xué)年第2學(xué)期計(jì)算機(jī)網(wǎng)絡(luò)課程設(shè)計(jì)DAY1:題目:VS2013/MFC基于對(duì)話框編程學(xué)院名稱(chēng): 班級(jí)學(xué)號(hào): 學(xué)生姓名: 教師姓名: 2016年 7 月 1. 創(chuàng)建MFC工程(1)雙擊打開(kāi) VS2013,進(jìn)入起始頁(yè),在左側(cè)開(kāi)始處選擇“新建項(xiàng)目”;或者選擇菜單欄中“文件”,依次選擇“新建”、“項(xiàng)目”。(2)選擇新建項(xiàng)目后,在新建項(xiàng)目對(duì)話框中選擇 模塊-Visual C+-MFC-MFC應(yīng)用程序,并確定好存放路徑和項(xiàng)目名稱(chēng),點(diǎn)擊“確定”。 (3)進(jìn)入應(yīng)用程序向?qū)В婚_(kāi)始會(huì)給出默認(rèn)的項(xiàng)目配置,點(diǎn)擊“下一步”即可。 (4)選擇“基于對(duì)話框”,MFC可以選擇在靜態(tài)庫(kù)中使用,或者在共
2、享DLL中使用。一般選擇共享使用就行,靜態(tài)庫(kù)中使用會(huì)把所有用到的 dll 集成到 exe 文件中,最終生成的文件一般可以直接使用,但占用更大空間。選擇主框架樣式,可以自由選擇是否添加最小化框、最大化框。如果覺(jué)得沒(méi)必要“關(guān)于”對(duì)話框也可以去掉,對(duì)話框標(biāo)題一般不需要更改。 (6)高級(jí)功能一般默認(rèn)即可,但如果用不上“ActiveX 控件”可以去掉勾選;如果需要涉及網(wǎng)絡(luò)編程就把“windows 套接字”選上。不過(guò)沒(méi)選上也不要緊,在程序中可以自己添加部分代碼導(dǎo)入套接字。 (7)最后是自動(dòng)生成的兩個(gè)類(lèi)的頭文件和源文件名稱(chēng),可以修改基類(lèi),但一般不用改,默認(rèn)完成就行。至此,一個(gè)基于對(duì)話框的MFC項(xiàng)目就創(chuàng)建好了
3、。 2. MFC執(zhí)行流程(1)每創(chuàng)建一個(gè)項(xiàng)目,一般會(huì)包含 3 個(gè)類(lèi),“關(guān)于”對(duì)話框類(lèi)、主對(duì)話框類(lèi)以及用于初始化項(xiàng)目的 App 類(lèi),假如項(xiàng)目名稱(chēng)為 Demo,那么這三個(gè)類(lèi)分別為 CAboutDlg、CDemoDlg、CDemoApp。 項(xiàng)目生成后,都會(huì)生成一個(gè)屬于 CDemoApp 類(lèi)的 theApp 對(duì)象,對(duì)本應(yīng)用程序?qū)嵗?,這個(gè)在CDemoApp.cpp文件中定義,創(chuàng)建時(shí)調(diào)用構(gòu)造函數(shù)CDemoApp:CDemoApp();這就是程序創(chuàng)建的第一步。 接下來(lái)程序會(huì)調(diào)用winmain函數(shù),這個(gè)在項(xiàng)目文件中找不到,但可以在VS2013的安裝路徑下找到,其函數(shù)聲明為: int AFXAPI AfxWi
4、nMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,_In_ LPTSTR lpCmdLine, int nCmdShow); 調(diào)用完winmain后,就通過(guò) InitInstance()函數(shù)初始化窗口,包括注冊(cè)、創(chuàng)建和顯示對(duì)話框,InitInstance函數(shù)是CDemoApp類(lèi)中除構(gòu)造函數(shù)以外唯一的成員函數(shù)。 一般不需要修改這部分程序,但有些時(shí)候可以添加部分代碼,比如需要?jiǎng)?chuàng)建多個(gè)對(duì)話框時(shí),剛啟動(dòng)時(shí)彈出的對(duì)話框(比如用于登錄)不是主對(duì)話框,就可以在這個(gè)函數(shù)里創(chuàng)建主對(duì)話框之前調(diào)用登錄對(duì)話框,這樣就可以設(shè)置啟動(dòng)時(shí)的默認(rèn)對(duì)話框了。 (5)應(yīng)用程序創(chuàng)建
5、完了,程序開(kāi)始運(yùn)行了,于是進(jìn)入消息循環(huán),windows程序的事件都是消息驅(qū)動(dòng) 的,每產(chǎn)生一個(gè)消息就觸發(fā)一個(gè)響應(yīng)事件,消息和事件通過(guò)消息映射DECLARE_MESSAGE_MAP()聯(lián)系在一起。 默認(rèn)包含三個(gè)消息: ON_WM_SYSCOMMAND() /響應(yīng)控制指令 ON_WM_PAINT() /響應(yīng)繪圖消息,用于刷新窗口 ON_WM_QUERYDRAGICON() /當(dāng)用戶拖動(dòng)最小化窗口時(shí)取得光標(biāo) (6)當(dāng)用戶關(guān)閉應(yīng)用程序時(shí),會(huì)發(fā)送一個(gè) WM_CLOSE 消息,程序響應(yīng)后結(jié)束程序,如何在點(diǎn)擊關(guān)閉時(shí)需要彈出其他對(duì)話框(比如用于提示保存),可以通過(guò)類(lèi)向?qū)砑?WM_CLOSE 消息處理函數(shù),變添
6、加相關(guān)處理程序,比如: void CDemoDlg:OnClose() if (MessageBox(_T(確定退出嗎), _T(提示), MB_YESNO|MB_ICONWARNING) = IDNO) return; CDialogEx:OnClose(); 這樣,一個(gè)應(yīng)用程序通過(guò)定義,初始化,由winmain開(kāi)始,注冊(cè)、創(chuàng)建、顯示窗口,消息響應(yīng),程序終止 完成了他的運(yùn)行周期。 3. 對(duì)話框類(lèi)(1) 首先看看對(duì)話框類(lèi)的繼承關(guān)系,新建的項(xiàng)目類(lèi)派生于CDialogEx類(lèi),CDialogEx在CDialog類(lèi)的基礎(chǔ)上進(jìn)行了擴(kuò)展,而CDialog派生于窗口類(lèi)CWnd,說(shuō)明對(duì)話框也屬于一種窗口。這樣
7、對(duì)于對(duì)話框類(lèi)的繼承關(guān)系就有了一定了解。 (2) 打開(kāi)項(xiàng)目的頭文件,最上面的#pragma once表示后面的頭文件只編譯一次;默認(rèn)生成的函數(shù)有: CDemoDlg(CWnd* pParent = NULL); / 標(biāo)準(zhǔn)構(gòu)造函數(shù) virtual void DoDataExchange(CDataExchange* pDX); / DDX/DDV 支持 / 生成的消息映射函數(shù) virtual BOOL OnInitDialog(); afx_msg void OnSysCommand(UINT nID, LPARAM lParam); afx_msg void OnPaint(); afx_msg
8、 HCURSOR OnQueryDragIcon(); DECLARE_MESSAGE_MAP() / 消息映射的聲明 三個(gè)消息在前一經(jīng)驗(yàn)已經(jīng)介紹過(guò),構(gòu)造函數(shù)自然是創(chuàng)建對(duì)話框時(shí)自動(dòng)調(diào)用, DoDataExchange函數(shù)用于存放各類(lèi)控件的變量信息,OnInitDialog用來(lái)初始化對(duì)話框。(3) 打開(kāi)源文件可以看到各個(gè)函數(shù)的定義,“關(guān)于”對(duì)話框類(lèi)的成員函數(shù)和消息映射也在這里,不多述。先講述構(gòu)造函數(shù) CDemoDlg(),通過(guò)類(lèi)向?qū)傻淖远x變量或者控件的關(guān)聯(lián)變量都會(huì)在構(gòu)造函數(shù)中初始化一個(gè)值,不過(guò)開(kāi)發(fā)者也可以直接在頭文件定義變量,并手動(dòng)在構(gòu)造函數(shù)中添加初始化語(yǔ)句。 所以說(shuō),構(gòu)造函數(shù)是個(gè)賦初值的
9、好地方。 再來(lái)看 DoDataExchange 函數(shù),在對(duì)話框中添加新的控件并通過(guò)類(lèi)向?qū)Фx了相關(guān)變量后,都會(huì)在這個(gè)用于數(shù)據(jù)交換的函數(shù)中說(shuō)明,添加變量的最大最小值也會(huì)在這里體現(xiàn)。 下面是消息映射,定義了所有消息的來(lái)源和處理函數(shù),對(duì)于自定義消息或者某些無(wú)法通過(guò)類(lèi)向?qū)瓿傻南ⅲ梢允謩?dòng)在這里添加映射關(guān)系,并在別處添加對(duì)應(yīng)的處理函數(shù)。 初始化函數(shù)OnInitDialog,默認(rèn)用來(lái)設(shè)置圖標(biāo)和菜單,很多時(shí)候有些操作需要在啟動(dòng)對(duì)話框前就做好,比如說(shuō)某些控件的初始狀態(tài)(按鈕是否可視、是否可操作),這些初始化的設(shè)置都可以在OnInitDialog函數(shù)中添加,最 好 在提示語(yǔ)“/ TODO: 在此添加額外的初
10、始化代碼”的下面添加。 系統(tǒng)指令響應(yīng)函數(shù) OnSysCommand,默認(rèn)處理窗口最小化和最大化指令等,并會(huì)根據(jù)是否選中“關(guān)于”決定是否彈出“關(guān)于”對(duì)話框。這個(gè)函數(shù)一般不需要修改。 繪圖消息響應(yīng)函數(shù)OnPaint 用于繪制窗口和圖標(biāo),其中CRect是個(gè)存儲(chǔ)窗口大小的結(jié)構(gòu)體。OnQueryDragIcon函數(shù)用于返回光標(biāo),這不多講。 默認(rèn)生成的函數(shù)就這么多,其他常用的消息有定時(shí)器消息 WM_TIMER、窗口關(guān)閉消息WM_CLOSE、應(yīng)用程序結(jié)束消息 WM_DESTROY、按鈕按下消息 WM_KEYDOWN 等。而常用的虛函數(shù)一般有PreTranslateMessage、PreCreateWindo
11、w等,這些以后用到再具體說(shuō)明。 4. 按鈕的使用 按鈕(Button)可以說(shuō)是對(duì)話框中最常用的控件之一,也是人機(jī)交互中必不可少的控件之一。許多事件都是通過(guò)按鈕按下來(lái)觸發(fā)的。在工具箱中找到對(duì)話框,按鈕名稱(chēng)是Button。把對(duì)話框原有的按鈕和靜態(tài)文本刪除,從工具箱中添加兩個(gè)按鈕到對(duì)話框中。 選中任意一個(gè)按鈕,在屬性頁(yè)中可以查看按鈕的所有屬性。 一般需要修改的屬性只有兩個(gè),“Caption”項(xiàng)和“ID”項(xiàng),前者表示按鈕文本,后者是按鈕ID,就像是人的身份證號(hào)一樣是唯一的。 其余常用屬性: 1、Disabled:使能,為真(true)表示按鈕可以按下,為假(false)表示按鈕為灰,不能操作 2、Vi
12、sible:可見(jiàn),為真表示按鈕可見(jiàn),為假表示按鈕不可見(jiàn) 3、Multiline:多行,為真表示按鈕文本可以多行顯示,為假表示按鈕文本不可換行顯示 說(shuō)明:對(duì)于只有真假兩種選項(xiàng)的屬性,可以雙擊屬性名稱(chēng)進(jìn)行切換true或false。選中屬性名稱(chēng),在屬性頁(yè)最下方都會(huì)有屬性說(shuō)明。 說(shuō)明: 1、變量名一般以m_開(kāi)頭,后面部分為按鈕功能的說(shuō)明,這樣方便記憶和識(shí)別; 2、按鈕只有控件型的變量; 3、如果有必要的話可以添加一定的注釋。5. 編輯框 編輯框(Edit Control)作為對(duì)話框中常用的控件之一,常用來(lái)輸入文本或者顯示文本,比如用戶名和密碼的輸入,當(dāng)前數(shù)據(jù)的顯示等等都少不了編輯框。 從工具箱中找到編
13、輯框(Edit Control),拖動(dòng)到對(duì)話框中。首先選中任意一個(gè)編輯框,看看編輯框都有哪些屬性,其中常用到屬性有: Multiline:多行,表示內(nèi)容可以多行顯示,一般記錄性的編輯框需要多行; Password:密碼,表示文本以密碼形式呈現(xiàn),一般用來(lái)輸出密碼; Read only:只讀,表示文本內(nèi)容只能讀不能寫(xiě); Number:數(shù)字,表示只能輸入數(shù)字; Lowercase:小寫(xiě),所有字母全部自動(dòng)轉(zhuǎn)換為小寫(xiě)顯示; Uppercase:大寫(xiě),所有字母全部自動(dòng)轉(zhuǎn)換為大寫(xiě)顯示; Horizontal scroll:水平滾動(dòng)條,需要先選中Multiline屬性; Vertical scroll:垂直滾
14、動(dòng)條,需要先選中Multiline屬性; 成績(jī): 2015-2016學(xué)年第2學(xué)期計(jì)算機(jī)網(wǎng)絡(luò)課程設(shè)計(jì)DAY2:題目:SOCKET編程學(xué)院名稱(chēng): 班級(jí)學(xué)號(hào): 學(xué)生姓名: 教師姓名: 2016年 7 月 1. Socket簡(jiǎn)介 80年代初,美國(guó)政府的高級(jí)研究工程機(jī)構(gòu)(ARPA)給加利福尼亞大學(xué)Berkeley分校提供了資金,讓他們?cè)赨NIX操作系統(tǒng)下實(shí)現(xiàn)TCP/IP協(xié)議。在這個(gè)項(xiàng)目中,研究人員為T(mén)CP/IP網(wǎng)絡(luò)通信開(kāi)發(fā)了一個(gè)API(應(yīng)用程序接口)。這個(gè)API稱(chēng)為Socket接口(套接字)。今天,SOCKET接口是TCP/IP網(wǎng)絡(luò)最為通用的API,也是在INTERNET上進(jìn)行應(yīng)用開(kāi)發(fā)最為通用的API。
15、 90年代初,由Microsoft聯(lián)合了其他幾家公司共同制定了一套WINDOWS下的網(wǎng)絡(luò)編程接口,即WindowsSockets規(guī)范。它是BerkeleySockets的重要擴(kuò)充,主要是增加了一些異步函數(shù),并增加了符合Windows消息驅(qū)動(dòng)特性的網(wǎng)絡(luò)事件異步選擇機(jī)制。WINDOWSSOCKETS規(guī)范是一套開(kāi)放的、支持多種協(xié)議的Windows下的網(wǎng)絡(luò)編程接口。從1991年的1.0版到1995年的2.0.8版,經(jīng)過(guò)不斷完善并在Intel、Microsoft、Sun、SGI、Informix、Novell等公司的全力支持下,已成為Windows網(wǎng)絡(luò)編程的事實(shí)上的標(biāo)準(zhǔn)。目前,在實(shí)際應(yīng)用中的WINDOW
16、SSOKCETS規(guī)范主要有1.1版和2.0版。兩者的最重要區(qū)別是1.1版只支持TCP/IP協(xié)議,而2.0版可以支持多協(xié)議。2.0版有良好的向后兼容性,任何使用1.1版的源代碼,二進(jìn)制文件,應(yīng)用程序都可以不加修改地在2.0規(guī)范下使用。SOCKET實(shí)際在計(jì)算機(jī)中提供了一個(gè)通信端口,可以通過(guò)這個(gè)端口與任何一個(gè)具有SOCKET接口的計(jì)算機(jī)通信。應(yīng)用程序在網(wǎng)絡(luò)上傳輸,接收的信息都通過(guò)這個(gè)SOCKET接口來(lái)實(shí)現(xiàn)。在應(yīng)用開(kāi)發(fā)中就像使用文件句柄一樣,可以對(duì)SOCKET句柄進(jìn)行讀,寫(xiě)操作。Socket可以支持?jǐn)?shù)據(jù)的發(fā)送和接收,它會(huì)定義一種稱(chēng)為套接字的變量,發(fā)送數(shù)據(jù)時(shí)首先創(chuàng)建套接字,然后使用該套接字的sendto
17、等方法對(duì)準(zhǔn)某個(gè)IP/端口進(jìn)行數(shù)據(jù)發(fā)送;接收端也首先創(chuàng)建套接字,然后將該套接字綁定到一個(gè)IP/端口上,所有發(fā)向此端口的數(shù)據(jù)會(huì)被該套接字的recv等函數(shù)讀出。如同讀出文件中的數(shù)據(jù)一樣。2. 所需的頭文件、庫(kù)文件和DLL對(duì)于目前使用最廣泛的Windows Socket2.0版本,所需的一些文件如下(以安裝了VC6為例說(shuō)明其物理位置):l頭文件winsock2.h,通常處于C:Program FilesMicrosoft Visual StudioVC98INCLUDE;查看該頭文件可知其中又包含了windows.h和pshpack4.h頭文件,因此在windows中的一些常用API都可以使用;l庫(kù)文
18、件Ws2_32.lib,通常處于C:Program FilesMicrosoft Visual StudioVC98Lib;lDLL文件Ws2_32.dll,通常處于C:WINDOWSsystem323. 部分類(lèi)型與函數(shù)SOCKET類(lèi)型 SOCKET是socket套接字類(lèi)型,在WINSOCK2.H中有如下定義: typedef unsigned int u_int; typedef u_intSOCKET; 可知套接字實(shí)際上就是一個(gè)無(wú)符號(hào)整型,它將被Socket環(huán)境管理和使用。套接字將被創(chuàng)建、設(shè)置、用來(lái)發(fā)送和接收數(shù)據(jù),最后會(huì)被關(guān)閉。WORD 類(lèi)型 WORD類(lèi)型是一個(gè)16位的無(wú)符號(hào)整型,在WTY
19、PES.H中被定義為: typedef unsigned short WORD;其目的是提供兩個(gè)字節(jié)的存儲(chǔ),在Socket中這兩個(gè)字節(jié)可以表示主版本號(hào)和副版本號(hào)。WSADATA類(lèi)型WSADATA類(lèi)型是一個(gè)結(jié)構(gòu),描述了Socket庫(kù)的一些相關(guān)信息,其結(jié)構(gòu)定義如下:typedef struct WSAData WORDwVersion; WORDwHighVersion; charszDescriptionWSADESCRIPTION_LEN+1; charszSystemStatusWSASYS_STATUS_LEN+1; unsigned shortiMaxSockets; unsigned
20、shortiMaxUdpDg; char FAR *lpVendorInfo; WSADATA;typedef WSADATA FAR *LPWSADATA;值得注意的就是wVersion字段,存儲(chǔ)了Socket的版本類(lèi)型。LPWSADATA是WSADATA的指針類(lèi)型。它們不用程序員手動(dòng)填寫(xiě),而是通過(guò)Socket的初始化函數(shù)WSAStartup讀取出來(lái)。Socket函數(shù) socket的創(chuàng)建函數(shù),其定義為: SOCKET PASCAL FAR socket (int af, int type, int protocol); 第一個(gè)參數(shù)為int af,代表網(wǎng)絡(luò)地址族,目前只有一種取值是有效的,即A
21、F_INET,代表internet地址族; 第二個(gè)參數(shù)為int type,代表網(wǎng)絡(luò)協(xié)議類(lèi)型,SOCK_DGRAM代表UDP協(xié)議,SOCK_STREAM代表TCP協(xié)議; 第三個(gè)參數(shù)為int protocol,指定網(wǎng)絡(luò)地址族的特殊協(xié)議,目前無(wú)用,賦值0即可。返回值為SOCKET,若返回INVALID_SOCKET則失敗。5) sockaddr_in、in_addr類(lèi)型,inet_addr、inet_ntoa函數(shù) sockaddr_in定義了socket發(fā)送和接收數(shù)據(jù)包的地址,定義: struct sockaddr_in short sin_family; u_short sin_port; str
22、uctin_addr sin_addr; charsin_zero8; ; 其中in_addr的定義如下: 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; S_un; 首先闡述in_addr的含義,很顯然它是一個(gè)存儲(chǔ)ip地址的聯(lián)合體,有三種表達(dá)方式:第一種用四個(gè)字節(jié)來(lái)表示IP地址的四個(gè)數(shù)字;第二種用兩個(gè)雙字節(jié)來(lái)表示IP地址;第三種用一個(gè)長(zhǎng)整型來(lái)表示IP地址。 給in_addr賦值的一種最簡(jiǎn)單方法是使用inet_addr
23、函數(shù),它可以把一個(gè)代表IP地址的字符串賦值轉(zhuǎn)換為in_addr類(lèi)型,如 addrto.sin_addr.s_addr=inet_addr(192.168.0.2); 其反函數(shù)是inet_ntoa,可以把一個(gè)in_addr類(lèi)型轉(zhuǎn)換為一個(gè)字符串。 sockaddr_in的含義比in_addr的含義要廣泛,其各個(gè)字段的含義和取值如下:第一個(gè)字段short sin_family,代表網(wǎng)絡(luò)地址族,如前所述,只能取值A(chǔ)F_INET;第二個(gè)字段u_short sin_port,代表IP地址端口,由程序員指定;第三個(gè)字段structin_addr sin_addr,代表IP地址;第四個(gè)字段char sin_z
24、ero8,很搞笑,是為了保證sockaddr_in與SOCKADDR型的長(zhǎng)度相等而填充進(jìn)來(lái)的字段。 以下代表指明了廣播地址,端口號(hào)為7861的一個(gè)地址: sockaddr_in addrto;/發(fā)往的地址 memset(&addrto,0,sizeof(addrto); addrto.sin_family = AF_INET; /地址類(lèi)型為internetwork addrto.sin_addr.s_addr = INADDR_BROADCAST; /設(shè)置ip為廣播地址 addrto.sin_port = htons(7861); /端口號(hào)為78616) 發(fā)送和接收函數(shù) 在Socket中有兩套
25、發(fā)送和接收函數(shù),一是sendto和recvfrom;二是send和recv。前一套在函數(shù)參數(shù)中要指明地址;而后一套需要先將套接字和一個(gè)地址綁定,然后直接發(fā)送和接收,不需綁定地址。sendto的定義如下:int PASCAL FAR sendto (SOCKET s, const char FAR * buf, int len, int flags, const struct sockaddr FAR *to, int tolen);第一個(gè)參數(shù)就是套接字;第二個(gè)參數(shù)是要傳送的數(shù)據(jù)指針; 第三個(gè)參數(shù)是要傳送的數(shù)據(jù)長(zhǎng)度(字節(jié)數(shù)); 第四個(gè)參數(shù)是傳送方式的標(biāo)識(shí),如果不需要特殊要求則可以設(shè)置為0,其它值
26、請(qǐng)參考MSDN;第五個(gè)參數(shù)是目標(biāo)地址,注意這里使用的是sockaddr的指針;第六個(gè)參數(shù)是地址的長(zhǎng)度;返回值為整型,如果成功,則返回發(fā)送的字節(jié)數(shù),失敗則返回SOCKET_ERROR。send和recv是用來(lái)發(fā)送和接收數(shù)據(jù)的兩個(gè)重要函數(shù)。send只能在已經(jīng)連接的狀態(tài)下使用,而recv可以面向連接和非連接的狀態(tài)下使用。send的定義如下:int WSAAPI send(SOCKET s,const char FAR * buf, int len,int flags);其參數(shù)的含義和sendto中的前四個(gè)參數(shù)一樣。而recv的定義如下:int WSAAPI recv(SOCKET s,char FA
27、R * buf, int len,int flags);其參數(shù)含義與send中的參數(shù)含義一樣。 成績(jī): 2015-2016學(xué)年第2學(xué)期計(jì)算機(jī)網(wǎng)絡(luò)課程設(shè)計(jì)DAY3:題目:服務(wù)器端、客戶端設(shè)計(jì)學(xué)院名稱(chēng): 班級(jí)學(xué)號(hào): 學(xué)生姓名: 教師姓名: 2016年 7 月 1. 設(shè)計(jì)原理2. 具體設(shè)計(jì)(1)socket函數(shù):為了執(zhí)行網(wǎng)絡(luò)輸入輸出,一個(gè)進(jìn)程必須做的第一件事就是調(diào)用socket函數(shù)獲得一個(gè)文件描述符。#include int socket(int family,int type,int protocol); 返回:非負(fù)描述字成功-1失敗第一個(gè)參數(shù)指明了協(xié)議簇,目前支持5種協(xié)議簇,最常用的有AF_IN
28、ET(IPv4協(xié)議)和AF_INET6(IPv6協(xié)議);第二個(gè)參數(shù)指明套接口類(lèi)型,有三種類(lèi)型可選:SOCK_STREAM(字節(jié)流套接口)、SOCK_DGRAM(數(shù)據(jù)報(bào)套接口)和SOCK_RAW(原始套接口);如果套接口類(lèi)型不是原始套接口,那么第三個(gè)參數(shù)就為0。(2)connect函數(shù):當(dāng)用socket建立了套接口后,可以調(diào)用connect為這個(gè)套接字指明遠(yuǎn)程端的地址;如果是字節(jié)流套接口,connect就使用三次握手建立一個(gè)連接;如果是數(shù)據(jù)報(bào)套接口,connect僅指明遠(yuǎn)程端地址,而不向它發(fā)送任何數(shù)據(jù)。#include int connect(int sockfd, const struct s
29、ockaddr * addr, socklen_t addrlen); 返回:0成功-1失敗第一個(gè)參數(shù)是socket函數(shù)返回的套接口描述字;第二和第三個(gè)參數(shù)分別是一個(gè)指向套接口地址結(jié)構(gòu)的指針和該結(jié)構(gòu)的大小。 這些地址結(jié)構(gòu)的名字均已“sockaddr_”開(kāi)頭,并以對(duì)應(yīng)每個(gè)協(xié)議族的唯一后綴結(jié)束。以IPv4套接口地址結(jié)構(gòu)為例,它以“sockaddr_in”命名,定義在頭文件;以下是結(jié)構(gòu)體的內(nèi)容:struct in_addr in_addr_t s_addr; /* IPv4地址 */;struct sockaddr_in uint8_t sin_len; /* 無(wú)符號(hào)的8位整數(shù) */sa_famil
30、y_t sin_family;/* 套接口地址結(jié)構(gòu)的地址簇,這里為AF_INET */in_port_t sin_port; /* TCP或UDP端口 */struct in_addr sin_addr;char sin_zero8; ;(3)bind函數(shù):為套接口分配一個(gè)本地IP和協(xié)議端口,對(duì)于網(wǎng)際協(xié)議,協(xié)議地址是32位IPv4地址或128位IPv6地址與16位的TCP或UDP端口號(hào)的組合;如指定端口為0,調(diào)用bind時(shí)內(nèi)核將選擇一個(gè)臨時(shí)端口,如果指定一個(gè)通配IP地址,則要等到建立連接后內(nèi)核才選擇一個(gè)本地IP地址。#include int bind(int sockfd, const str
31、uct sockaddr * server, socklen_t addrlen);返回:0成功-1失敗第一個(gè)參數(shù)是socket函數(shù)返回的套接口描述字;第二和第第三個(gè)參數(shù)分別是一個(gè)指向特定于協(xié)議的地址結(jié)構(gòu)的指針和該地址結(jié)構(gòu)的長(zhǎng)度。(4)listen函數(shù):listen函數(shù)僅被TCP服務(wù)器調(diào)用,它的作用是將用sock創(chuàng)建的主動(dòng)套接口轉(zhuǎn)換成被動(dòng)套接口,并等待來(lái)自客戶端的連接請(qǐng)求。#include int listen(int sockfd,int backlog); 返回:0成功-1失敗第一個(gè)參數(shù)是socket函數(shù)返回的套接口描述字;第二個(gè)參數(shù)規(guī)定了內(nèi)核為此套接口排隊(duì)的最大連接個(gè)數(shù)。由于listen
32、函數(shù)第二個(gè)參數(shù)的原因,內(nèi)核要維護(hù)兩個(gè)隊(duì)列:以完成連接隊(duì)列和未完成連接隊(duì)列。未完成隊(duì)列中存放的是TCP連接的三路握手為完成的連接,accept函數(shù)是從以連接隊(duì)列中取連接返回給進(jìn)程;當(dāng)以連接隊(duì)列為空時(shí),進(jìn)程將進(jìn)入睡眠狀態(tài)。(5)accept函數(shù):accept函數(shù)由TCP服務(wù)器調(diào)用,從已完成連接隊(duì)列頭返回一個(gè)已完成連接,如果完成連接隊(duì)列為空,則進(jìn)程進(jìn)入睡眠狀態(tài)。#include int accept(int listenfd, struct sockaddr *client, socklen_t * addrlen); 回:非負(fù)描述字成功-1失敗 第一個(gè)參數(shù)是socket函數(shù)返回的套接口描述字;第二
33、個(gè)和第三個(gè)參數(shù)分別是一個(gè)指向連接方的套接口地址結(jié)構(gòu)和該地址結(jié)構(gòu)的長(zhǎng)度;該函數(shù)返回的是一個(gè)全新的套接口描述字;如果對(duì)客戶段的信息不感興趣,可以將第二和第三個(gè)參數(shù)置為空。(6)write和read函數(shù):當(dāng)服務(wù)器和客戶端的連接建立起來(lái)后,就可以進(jìn)行數(shù)據(jù)傳輸了,服務(wù)器和客戶端用各自的套接字描述符進(jìn)行讀/寫(xiě)操作。因?yàn)樘捉幼置枋龇彩且环N文件描述符,所以可以用文件讀/寫(xiě)函數(shù)write()和read()進(jìn)行接收和發(fā)送操作。 write()函數(shù)用于數(shù)據(jù)的發(fā)送。 #include int write(int sockfd, char *buf, int len); 返回:非負(fù)成功-1失敗參數(shù)sockfd是套接字
34、描述符,對(duì)于服務(wù)器是accept()函數(shù)返回的已連接套接字描述符,對(duì)于客戶端是調(diào)用socket()函數(shù)返回的套接字描述符;參數(shù)buf是指向一個(gè)用于發(fā)送信息的數(shù)據(jù)緩沖區(qū);len指明傳送數(shù)據(jù)緩沖區(qū)的大小。 read()函數(shù)用于數(shù)據(jù)的接收。 #include int read(int sockfd, char *buf, intlen); 返回:非負(fù)成功-1失敗參數(shù)sockfd是套接字描述符,對(duì)于服務(wù)器是accept()函數(shù)返回的已連接套接字描述符,對(duì)于客戶端是調(diào)用socket()函數(shù)返回的套接字描述符;參數(shù)buf是指向一個(gè)用于接收信息的數(shù)據(jù)緩沖區(qū);len指明接收數(shù)據(jù)緩沖區(qū)的大小。(7)send和r
35、ecv函數(shù):TCP套接字提供了send()和recv()函數(shù),用來(lái)發(fā)送和接收操作。這兩個(gè)函數(shù)與write()和read()函數(shù)很相似,只是多了一個(gè)附加的參數(shù)。send()函數(shù)用于數(shù)據(jù)的發(fā)送。#include #include ssize_t send(int sockfd, const void *buf, size_t len, int flags); 返回:返回寫(xiě)出的字節(jié)數(shù)成功-1失敗前3個(gè)參數(shù)與write()相同,參數(shù)flags是傳輸控制標(biāo)志。 recv()函數(shù)用于數(shù)據(jù)的發(fā)送。 #include #include ssize_t recv(int sockfd, void *buf, s
36、ize_t len, int flags); 返回:返回讀入的字節(jié)數(shù)成功-1失敗前3個(gè)參數(shù)與read()相同,參數(shù)flags是傳輸控制標(biāo)志。 成績(jī): 2015-2016學(xué)年第2學(xué)期計(jì)算機(jī)網(wǎng)絡(luò)課程設(shè)計(jì)題目:多終端數(shù)據(jù)采集系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)學(xué)院名稱(chēng): 班級(jí)學(xué)號(hào): 學(xué)生姓名: 教師姓名: 2016年 7 月 一、實(shí)驗(yàn)要求 (1)按照所給出的通信協(xié)議格式,利用 UDP 通信,實(shí)現(xiàn)多終端數(shù)據(jù)采集并顯示【必做項(xiàng)】; (2)進(jìn)一步可以在服務(wù)器中各終端上傳數(shù)據(jù)進(jìn)行數(shù)據(jù)庫(kù)保存,在此基礎(chǔ)上開(kāi)發(fā)基于網(wǎng)頁(yè)或手機(jī) APP 的多終端數(shù)據(jù)實(shí)時(shí)監(jiān)控;【選做項(xiàng)】 (3)根據(jù)自己所設(shè)計(jì)實(shí)現(xiàn)的任務(wù),完成課程設(shè)計(jì)報(bào)告。 二、 終端與服
37、務(wù)器之間通信協(xié)議 (1)幀格式(固定部分 13B+數(shù)據(jù)部分幀長(zhǎng)) 信息頭2B版本號(hào)1B幀長(zhǎng)2B類(lèi)型1B幀號(hào)1B數(shù)據(jù)校驗(yàn)和4B結(jié)束標(biāo)志 2B0 xFFFFCRC320 xFFF7其中: 幀號(hào),取值范圍 1255;一般一種命令包組織成一個(gè)幀,也可以稱(chēng)其為邏輯幀,內(nèi) 容強(qiáng)調(diào)其邏輯上的完整性。 版本號(hào),1 字節(jié),缺省為 0. 幀長(zhǎng):為每個(gè)物理幀的數(shù)據(jù)部分長(zhǎng)度,即有效位長(zhǎng)度,整個(gè)幀長(zhǎng)-13(固定部分長(zhǎng) 度),一般其取值為 0490。2 字節(jié)。 類(lèi)型:保留,缺省值 1。 校驗(yàn)和:CRC32 校驗(yàn),只是對(duì)版本號(hào)到數(shù)據(jù)部分的字節(jié)內(nèi)容加校驗(yàn),即信息頭和 結(jié)束標(biāo)志部分不在校驗(yàn)之列,校驗(yàn)算法見(jiàn)本文檔最后部分。 命令
38、幀(即幀的數(shù)據(jù)部分) 終端ID5B命令1B數(shù)據(jù)其中: 終端 ID:5 個(gè)字節(jié)的 BCD 編號(hào)。 命令:小于 128,大于 128 為異常命令,即異常命令=0 x80+命令。 (3) 終端與服務(wù)器之間通信流程 終端上傳數(shù)據(jù)包給服務(wù)器,服務(wù)器接收,發(fā)送確認(rèn)包給終端終端-服務(wù)器命令 序號(hào) 數(shù)據(jù)包類(lèi)型 序號(hào)數(shù)據(jù)包類(lèi)型命令碼 1B說(shuō)明1數(shù)據(jù)上傳數(shù)據(jù)包0 x13網(wǎng)絡(luò)其中數(shù)據(jù)上傳數(shù)據(jù)包格式如下 命令碼 1B上傳記錄數(shù) 1B上傳數(shù)據(jù)0 x13n110按時(shí)間升序排列的采集狀態(tài)數(shù)據(jù)42*n 所上傳的 42 字節(jié)狀態(tài)數(shù)據(jù)的組織結(jié)構(gòu)表 名稱(chēng)類(lèi)型字節(jié)數(shù)備注1采集時(shí)間byte6YYMMDDhhmmss2經(jīng)度字節(jié)數(shù)組51字
39、節(jié)符號(hào)位(0正1 負(fù))+1字節(jié)整數(shù)+3字節(jié)小數(shù)(BCD編碼),東經(jīng)正數(shù),西經(jīng)為負(fù)數(shù)3緯度字節(jié)數(shù)組51字節(jié)符號(hào)位(0正1 負(fù))+1字節(jié)整數(shù)+3字節(jié)小數(shù)(BCD編碼)4水溫字節(jié)數(shù)組4Real,缺省值05PH值字節(jié)數(shù)組4Real,缺省值06電導(dǎo)率字節(jié)數(shù)組4Real,缺省值07濁度字節(jié)數(shù)組4Real,缺省值08溶解氧字節(jié)數(shù)組4Real,缺省值09氨氮字節(jié)數(shù)組4Real,缺省值010上傳標(biāo)志byte10:未上傳,1:已上傳,缺省 011故障代碼byte1位號(hào):0:Modbus 故障,1:上傳故障,2:連接管理服務(wù)器故障,3:位移報(bào)警,4:停電故障,5:系統(tǒng)故障。42服務(wù)器-終端命令列表 序號(hào) 數(shù)據(jù)包類(lèi)型
40、 序號(hào)數(shù)據(jù)包類(lèi)型命令碼 1B說(shuō)明1確認(rèn)包0 x13網(wǎng)絡(luò)其中確認(rèn)包格式如下 命令碼 1B幀號(hào) 1B發(fā)送方時(shí)間 7B0 x13被確認(rèn)的幀號(hào)YYYYMMDDhhmmss(BCD碼) 終端與服務(wù)器通信過(guò)程的說(shuō)明: 終端每隔一定時(shí)間(默認(rèn)為 10 秒)發(fā)送一個(gè)數(shù)據(jù)上傳包,服務(wù)器收到數(shù)據(jù)上傳包后,返回確認(rèn)包; 服務(wù)器在規(guī)定的數(shù)據(jù)上傳等待計(jì)時(shí)長(zhǎng)度時(shí)間內(nèi)(默認(rèn)為 1 分鐘)沒(méi)有收到終端的任何信息,則認(rèn)為該終端不在線(即離線)。 如果終端在規(guī)定的時(shí)間內(nèi)(默認(rèn)為 5 秒)沒(méi)有收到服務(wù)器確認(rèn)包,則重發(fā)該上傳數(shù)據(jù)包,每個(gè)上傳數(shù)據(jù)包最多重發(fā)一次,還是沒(méi)收到確認(rèn)的話則丟去,延時(shí) 30 秒再發(fā)送下一個(gè)上傳數(shù)據(jù)包。 終端與服
41、務(wù)器通信采用 UDP 方式。 數(shù)據(jù)幀校驗(yàn)和計(jì)算方法三、實(shí)現(xiàn)方案新建兩個(gè)基于對(duì)話框的工程,分別為服務(wù)器、客戶端。服務(wù)器端界面設(shè)計(jì) 在服務(wù)器端添加兩個(gè)Edit:一個(gè)顯示窗口IDC_EDIT1(點(diǎn)擊右鍵選擇Properties-Styles,選中Multiline,Vertical scroll、Read-only三項(xiàng)),一個(gè)輸入窗口IDC_EDIT2。然后增加一個(gè)發(fā)送按鈕:IDC_BtnSend,名稱(chēng)為發(fā)送??蛻舳私缑嬖O(shè)計(jì) 在客戶端端添加三個(gè)Edit:一個(gè)顯示窗口IDC_EDIT1(點(diǎn)擊右鍵選擇Properties-Styles,選中Multiline,Vertical scroll、Read-o
42、nly三項(xiàng)),一個(gè)輸入窗口IDC_EDIT2,一個(gè)IP地址輸入窗口IDC_EDIT3。再增加兩個(gè)按鈕:一個(gè)發(fā)送按鈕IDC_SEND,名稱(chēng)為發(fā)送,一個(gè)連接服務(wù)器按鈕IDC_btnConnect,名稱(chēng)為連接服務(wù)器。代碼實(shí)現(xiàn)(見(jiàn)附錄1)四、測(cè)試結(jié)果 正常接收狀態(tài) 關(guān)閉服務(wù)器后五、總結(jié)與展望這次課程設(shè)計(jì)和之前大不相同,很多知識(shí)都是第一次接觸,例如MFC、SOCKET網(wǎng)絡(luò)編程等等。一開(kāi)始無(wú)從下手,只能先從網(wǎng)絡(luò)上學(xué)習(xí)這些知識(shí),而時(shí)間又比較緊迫,所以起初進(jìn)度緩慢。待得初步熟悉了這些新知識(shí)以后,回過(guò)來(lái)再看這次課設(shè)就不再是那么迷茫了,有了一個(gè)大概的思路之后,設(shè)計(jì)也進(jìn)入了正軌,從對(duì)話框設(shè)計(jì)再到服務(wù)器端客戶端設(shè)計(jì),
43、雖然過(guò)程不是一帆風(fēng)順,但也是逐步推進(jìn)。大體設(shè)計(jì)結(jié)束之后,進(jìn)行調(diào)試,錯(cuò)誤百出,由于學(xué)習(xí)得不是很深入,很多錯(cuò)誤改起來(lái)也很棘手,尤其是各類(lèi)數(shù)據(jù)類(lèi)型之間的轉(zhuǎn)換錯(cuò)誤特別的多,百度、請(qǐng)教,各種嘗試,花費(fèi)了很長(zhǎng)一段時(shí)間才把程序修改成功。初次調(diào)試,雖然沒(méi)有語(yǔ)法上的錯(cuò)誤,但因?yàn)檫壿嬪e(cuò)誤,兩端無(wú)法連接,初次調(diào)試以失敗告終。不得不返回程序繼續(xù)去修改。主要的錯(cuò)誤是兩端的IP地址不同,以及接收發(fā)送字符串長(zhǎng)度有錯(cuò)。經(jīng)過(guò)多次調(diào)試,程序最終成功了。對(duì)于這個(gè)設(shè)計(jì),也有一些不足,服務(wù)器和客戶端與現(xiàn)實(shí)中的功能有所差異,多客戶端與服務(wù)器發(fā)送消息之間存在問(wèn)題,還有待改進(jìn)。總的而言,這次計(jì)算機(jī)網(wǎng)絡(luò)課設(shè)收獲頗豐,知識(shí)上學(xué)到了網(wǎng)絡(luò)編程,學(xué)會(huì)
44、如何設(shè)計(jì)一個(gè)簡(jiǎn)單的服務(wù)器端和客戶端實(shí)現(xiàn)兩端通信。以后踏入社會(huì)崗位最重要的是一個(gè)人的自學(xué)能力,尤其計(jì)算機(jī)這個(gè)行業(yè)技術(shù)日新月異,是離不開(kāi)不斷地學(xué)習(xí)的,這次的課設(shè)就完美地鍛煉了我們的自學(xué)和動(dòng)手能力,對(duì)于未來(lái)的就業(yè)和科研都有著重大意義。附錄1(只附上添加的代碼,自動(dòng)生成的不在其內(nèi))服務(wù)器端:在stdafx.h中添加 #include/ MFC socket extensions 在服務(wù)器Dlg.h中添加public:void update(CString s); 在服務(wù)器Dlg.h中添加private:CEdit*show_edit;CEdit*send_edit;2、在服務(wù)器Dlg.cpp中添加#i
45、nclude (加在#include stdafx.h之前) #include tchar.h #pragma comment(lib,WS2_32.lib) 新建兩個(gè)socket:SOCKET listen_sock; SOCKET sock; 聲明線程函數(shù) UINT server_thd(LPVOID p);3、在OnInitDialog()函數(shù)中添加: show_edit = (CEdit *)GetDlgItem(IDC_EDIT1);send_edit = (CEdit *)GetDlgItem(IDC_EDIT2);send_edit-SetFocus();char name80;
46、CString IP;hostent* pHost;gethostname(name, 128);/獲得主機(jī)名 pHost = gethostbyname(name);/獲得主機(jī)結(jié)構(gòu) IP = inet_ntoa(*(in_addr *)pHost-h_addr);update(本機(jī)IP地址: + IP);AfxBeginThread(&server_thd, 0);return TRUE; / 除非將焦點(diǎn)設(shè)置到控件,否則返回 TRUE /添加函數(shù)update() void C服務(wù)器Dlg:update(CString s) show_edit-ReplaceSel(s + rn); /添加線
47、程函數(shù)server_thd() UINT server_thd(LPVOID p) WSADATA wsaData; WORD wVersion; wVersion = MAKEWORD(2, 2); WSAStartup(wVersion, &wsaData); / WSAStartup(0 x0202, &wsaData); SOCKADDR_IN local_addr; SOCKADDR_IN client_addr; int iaddrSize = sizeof(SOCKADDR_IN); int res; char msg1024; C服務(wù)器Dlg * dlg = (C服務(wù)器Dlg
48、*)AfxGetApp()-GetMainWnd(); local_addr.sin_family = AF_INET; local_addr.sin_port = htons(5150); local_addr.sin_addr.s_addr = inet_addr(127.0.0.1); /local_addr.sin_addr.s_addr = htonl(INADDR_ANY); if (listen_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) = INVALID_SOCKET) dlg-update(創(chuàng)建監(jiān)聽(tīng)失敗); if (bi
49、nd(listen_sock, (struct sockaddr*) &local_addr, sizeof(SOCKADDR_IN) dlg-update(綁定錯(cuò)誤); listen(listen_sock, 1); if (sock = accept(listen_sock, (struct sockaddr *)&client_addr, &iaddrSize) = INVALID_SOCKET) dlg-update(accept 失敗); else CString port; port.Format(_T(%d), int(ntohs(client_addr.sin_port); d
50、lg-update(已連接來(lái)自: + CString(inet_ntoa(client_addr.sin_addr) + 端口: +port); /接收數(shù)據(jù) CString strRecv; while (1) if (res = recv(sock, msg, 1024, 0) = -1) dlg-update(失去連接); break; else msgres = 0; strRecv.Format(_T(client: %s), msg); dlg-update(strRecv); return 0;添加按鈕實(shí)現(xiàn)函數(shù)void C服務(wù)器Dlg:OnBnClickedBtnsend(): /
51、發(fā)送按鈕 void C服務(wù)器Dlg:OnBnClickedBtnsend() / TODO: 在此添加控件通知處理程序代碼 CString s; send_edit-GetWindowText(s); /char * msg; /msg = (char*)s.GetBuffer(s.GetLength(); if (send(sock, (const char *)s.GetBuffer(), (s.GetLength()+1)*2, 0) = SOCKET_ERROR) show_edit-ReplaceSel(_T(發(fā)送失敗rn); else if (s = ) MessageBox(_T
52、(請(qǐng)輸入信息); else show_edit-ReplaceSel(server: + s + rn);/消息上屏 send_edit-SetWindowText(_T();/清空輸入 send_edit-SetFocus();/重獲焦點(diǎn) 客戶端:1、在stdafx.h中添加 #include/ MFC socket extensions 在客戶端Dlg.h中添加public:void update(CString s); 在客戶端Dlg.h中添加private:CEdit *edit1; CButton *btnconn; CEdit *send_edit; CEdit *ip_edit;2、在客戶端Dlg.cpp中添加#include (加在#include stdafx.h之前) #include tchar.h #pragma comment(lib,WS2_32.lib) 新建兩個(gè)socket:SOCKET sock; 聲明線程函數(shù) UINT recv_thd(LPVOID p);在OnIn
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 家校共建合同:學(xué)院與家長(zhǎng)權(quán)益保障
- 國(guó)家機(jī)關(guān)勞動(dòng)合同樣本合同
- 工廠保安用工合同
- 消防課程安全課件
- 智能儀器儀表智能醫(yī)療應(yīng)用考核試卷
- 成人高考地理知識(shí)要點(diǎn)專(zhuān)項(xiàng)訓(xùn)練考核試卷
- 斯洛文尼亞網(wǎng)絡(luò)廣告競(jìng)爭(zhēng)格局洞察考核試卷
- 文化用品租賃業(yè)務(wù)項(xiàng)目管理考核試卷
- 機(jī)場(chǎng)航站樓空氣質(zhì)量控制考核試卷
- 2024信息物理融合智能系統(tǒng)實(shí)施流程
- DB11T 2033-2022 餐廚垃圾源頭減量操作要求
- 1.2 歌曲 《春天來(lái)了》 課件(11張)
- 【人教版】pep六年級(jí)英語(yǔ)下全冊(cè)教案(表格版)
- 護(hù)理培訓(xùn)師競(jìng)聘
- 北師大版小學(xué)數(shù)學(xué)五年級(jí)下冊(cè)同步課時(shí)練習(xí)試題含答案(全冊(cè))
- 4《我們的公共生活》第一課時(shí) 教學(xué)設(shè)計(jì)-2023-2024學(xué)年道德與法治五年級(jí)下冊(cè)統(tǒng)編版
- 2024年放射工作人員放射防護(hù)培訓(xùn)考試題及答案
- SH∕T 3097-2017 石油化工靜電接地設(shè)計(jì)規(guī)范
- 高中英語(yǔ)真題-高考英語(yǔ)語(yǔ)法填空專(zhuān)練(6)及答案
- 倉(cāng)儲(chǔ)物流中心物業(yè)管理服務(wù)費(fèi)報(bào)價(jià)單
- 室內(nèi)給水管道安裝安全技術(shù)交底
評(píng)論
0/150
提交評(píng)論