




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、 Windows Socket 網(wǎng)絡(luò)通信程序設(shè)計(jì)一、理論分析同步方式指的是發(fā)送方不等接收方響應(yīng),便接著發(fā)下個(gè)數(shù)據(jù)包的通信方式;而異步指發(fā)送方發(fā)出數(shù)據(jù)后,等收到接收方發(fā)回的響應(yīng),才發(fā)下一個(gè)數(shù)據(jù)包的通信方式。 阻塞套接字是指執(zhí)行此套接字的網(wǎng)絡(luò)調(diào)用時(shí),直到成功才返回,否則一直阻塞在此網(wǎng)絡(luò)調(diào)用上,比如調(diào)用recv()函數(shù)讀取網(wǎng)絡(luò)緩沖區(qū)中的數(shù)據(jù),如果沒有數(shù)據(jù)到達(dá),將一直掛在recv()這個(gè)函數(shù)調(diào)用上,直到讀到一些數(shù)據(jù),此函數(shù)調(diào)用才返回;而非阻塞套接字是指執(zhí)行此套接字的網(wǎng)絡(luò)調(diào)用時(shí),不管是否執(zhí)行成功,都立即返回。比如調(diào)用recv()函數(shù)
2、讀取網(wǎng)絡(luò)緩沖區(qū)中數(shù)據(jù),不管是否讀到數(shù)據(jù)都立即返回,而不會(huì)一直掛在此函數(shù)調(diào)用上。在實(shí)際Windows 網(wǎng)絡(luò)通信軟件開發(fā)中,異步非阻塞套接字是用的最多的。平常所說的C/S(客戶端/服務(wù)器)結(jié)構(gòu)的軟件就是異步非阻塞模式的。 使用的是傳統(tǒng)的socket (recv(),send() .)等。而且是阻塞模式,使用圖形界面MFC編寫 (VC 6.0)但為了能讓程序不出現(xiàn)假死現(xiàn)象( recv,accept 這樣的函數(shù)都會(huì)出現(xiàn)這樣的事情),所以采用了多線程技術(shù),其實(shí)也就是用了AfxBeginThread ,TerminateThread等等。這樣對(duì)于阻塞函數(shù)都讓他們?cè)谛陆⒌木€程里運(yùn)行
3、就好了。另外解決的一個(gè)大問題就是,創(chuàng)建的新線程無法對(duì)窗口進(jìn)行操作,比如要自在編輯框顯示一句話等等。如果直接取得窗口類的句柄操作,會(huì)出現(xiàn)wincore 的錯(cuò)誤,也就是跨線程錯(cuò)誤。主要原因也就是-MFC的線程被自己外部創(chuàng)建的線程調(diào)用就會(huì)有這個(gè)錯(cuò)誤。解決的方法就是在線程里用SendMessage給窗口發(fā)送一個(gè)自定義的消息。比如我這里用的就是 要實(shí)現(xiàn)這樣的方法在BEGIN_MESSAGE_MAP下面要添加ON_MESSAGE(WM_UpdateDATA, OnMyMessage) 綁定我自己的消息,這樣外部的線程就可以通過SendMessage來調(diào)用窗體的函數(shù)OnMy
4、Message了,用來顯示信息WM_UpdateDATA在stdafx.h中我自己定義為#define WM_UpdateDATA WM_USER+100 。定義一個(gè)自己的消息*/這樣只要外部給窗口SendMessage -> WM_UpdateDATA 就會(huì)讓窗口的onmymessage函數(shù)執(zhí)行了,具體要顯示的內(nèi)容放在一個(gè)全局變量就好了。 serverdlg.cpp 二、程序代碼/定義全局變量,方便各個(gè)工作線程和窗口線程的通信SOCKETsockuse,sock;int flag; /主要是用來標(biāo)志是否連接,用來控制一些循環(huán)和功能HWND m
5、ydlg; /記錄窗體的句柄HWND stopbutton; /記錄關(guān)閉連接按鈕的句柄 char buff200; /主要的緩沖區(qū),顯示數(shù)據(jù)使用,也供線程間通信使用 CWinThread* mainthread; /記錄線程的句柄 UINT FileTrans(LPVOID pParam) /發(fā)送文件的線程函數(shù) OPENFILENAMEA ofn; char szFile260; char path260; char filebuff100; int num; ZeroMemory(&ofn, sizeof(ofn); ofn.lStructS
6、ize = sizeof(ofn); ofn.hwndOwner = NULL; ofn.lpstrFile = szFile; ofn.lpstrFile0 = '0' ofn.nMaxFile = sizeof(szFile); ofn.lpstrFilter = "所有文件*.*0" ofn.nFilterIndex = 1; ofn.lpstrFileTitle = NULL; ofn.nMaxFileTitle = 0; ofn.lpstrInitialDir = NULL; ofn.Flags = 0; /以上的定義是為了建立一個(gè)文件打開對(duì)話框。
7、步驟/上來說都是固定的,這里只是借用一下 if (GetOpenFileNameA(&ofn)=FALSE) /判斷文件路徑取得是否正確 /若失敗則恢復(fù)建立MainControl線程,進(jìn)行數(shù)據(jù)接收處理。 mainthread=AfxBeginThread(MainControl,NULL); flag=1; /設(shè)定flag保證MainControl可以正常進(jìn)行循環(huán)return 0; memset(filebuff,0,100); /清空filebuff strcpy(path,ofn.lpstrFile); /將路徑拷貝到path中 strcpy(filebuff,"send
8、start"); send(sockuse,filebuff,strlen(filebuff),0); /發(fā)送請(qǐng)求信息 recv(sockuse,filebuff,100,0); /等待接收反饋信息 if(strcmp(filebuff,"sendagree") /若接收到的信息不是sendagree strcpy(buff,"對(duì)方接受錯(cuò)誤"); SendMessage(mydlg,WM_UpdateDATA,NULL,NULL); /發(fā)送給窗口消息,顯示信息 mainthread=AfxBeginThread(MainControl,NULL
9、); /恢復(fù)建立MainControl線程 flag=1; /設(shè)定flag保證MainControl循環(huán)正常 return 0;SendMessage(mydlg,WM_UpdateDATA,NULL,NULL); /發(fā)送給窗口消息,顯示信息 while(!feof(fp) num=fread(filebuff,1,100,fp); /文件結(jié)束前每次讀取100字節(jié) send(sockuse,filebuff,num,0); /發(fā)送,最后一次不足100字節(jié) /作為標(biāo)志,可以讓接受方知道文件結(jié)束 strcpy(buff,"發(fā)送完畢");SendMess
10、age(mydlg,WM_UpdateDATA,NULL,NULL); /發(fā)送給窗口消息,顯示信息memset(buff,0,100);fclose(fp); /關(guān)閉文件 flag=1; return 0; UINT FileRecv() /接收文件函數(shù) char sendbuff100; /發(fā)送緩沖區(qū)char recvbuff100; /接受緩沖區(qū)int num; /記錄每次接受的字節(jié)數(shù) CString szGetName; /記錄保存的文件路徑CFileDialog * lpszOpenFile; /定義一個(gè)CfileDialog對(duì)象
11、lpszOpenFile=new CFileDialog(false,"","",OFN_FILEMUSTEXIST|OFN_HIDEREADONLY,"文件類型(*.*)|*.*|");/生成一個(gè)對(duì)話框if(lpszOpenFile->DoModal()=IDOK)/假如點(diǎn)擊對(duì)話框確定按鈕szGetName = lpszOpenFile->GetPathName(); /得到打開文件的路徑/SetWindowText(szGetName); /在窗口標(biāo)題上顯示路徑delete lpszOpenFile; /釋放分配的對(duì)話
12、框memset(sendbuff,0,100); strcpy(sendbuff,"sendagree"); send(sockuse,sendbuff,strlen(sendbuff),0); /發(fā)送sendagree告知對(duì)方開始發(fā)送吧 SendMessage(mydlg,WM_UpdateDATA,NULL,NULL); /發(fā)送給窗口消息,顯/示信息 num=recv(sockuse,recvbuff,100,0); /接收數(shù)據(jù)FILE *fp=fopen(szGetName,"wb"); /打開文件,路徑為szGe
13、tNamefwrite(recvbuff,num,1,fp); /寫入之前的數(shù)據(jù) num=recv(sockuse,recvbuff,100,0); fwrite(recvbuff,num,1,fp); fclose(fp); /結(jié)束后關(guān)閉文件。 strcpy(buff,"接收完畢");SendMessage(mydlg,WM_UpdateDATA,NULL,NULL); /發(fā)送給窗口消息,/顯示信息return 0; int Addrlen=sizeof(sockaddr_in); /accept要用到的數(shù)值sockaddr_i
14、n ClientAddr; sockuse=accept(sock,(struct sockaddr FAR *)&ClientAddr,&Addrlen);/上一句的accept函數(shù)調(diào)用后會(huì)進(jìn)行阻塞,造成未返回時(shí)程序假死,使用了單獨(dú)的線程/就是為了防止這樣的現(xiàn)象發(fā)生flag=1; /返回成功后,設(shè)定flag保證MainControl循環(huán)正常strcpy(buff,"已經(jīng)連接!");SendMessage(mydlg,WM_UpdateDATA,NULL,NULL); /發(fā)送給窗口消/息,顯示信息mainthread=AfxBeginThread(MainC
15、ontrol,NULL); /建立MainControl線程 return 0; char recvbuff100; /接受緩沖區(qū)memset(buff,0,100);while(flag)memset(recvbuff,0,100); /每次接收前清空緩沖區(qū) recv(sockuse,recvbuff,100,0); /進(jìn)行阻塞接收數(shù)據(jù),如果不是用單獨(dú)的線程/會(huì)造成程序假死,這也就是為什么我的程序使用單獨(dú)的線程來處理 if(!strcmp(recvbuff,"end")SendMessag
16、e(stopbutton,BM_CLICK,NULL,NULL); /消息判斷為end則調(diào)用/窗口的OnButtonEnd函數(shù)來結(jié)束連接的清理工作。return 0;else if(!strcmp(recvbuff,"sendstart")/接受的消息判斷為"sendstart"則調(diào)用FileRecv() FileRecv(); else strcpy(buff,"client:");strcat(buff,recvbuff);SendMessage(mydlg,WM_UpdateDATA,NULL,NULL); /發(fā)送給/窗口消息,
17、顯示信息return 0; m_ctrlstop.EnableWindow(true); m_ctrlfile.EnableWindow(true);m_ctrlstart.EnableWindow(false);m_ctrlsend.EnableWindow(true); /以上使各個(gè)按鈕進(jìn)行使能 sockaddr_in ServerAddr; /開始建立socket WSADATA WSAData; if(WSAStartup(MAKEWORD(2,2),&WSAData)!=0)showmess("SOCKET 初始化錯(cuò)誤
18、rn");return; sock=socket(AF_INET,SOCK_STREAM,0); /采用流式套接字,ipv4if(sock=SOCKET_ERROR)showmess("SOCKET 創(chuàng)建錯(cuò)誤!rn");WSACleanup(); return; ServerAddr.sin_family=AF_INET; ServerAddr.sin_addr.s_addr=htonl(INADDR_ANY); /任意ip作為本機(jī)ip ServerAddr.sin_port=htons(2006); /使用2006端口 if(bind(sock,(s
19、truct sockaddr FAR*)&ServerAddr,sizeof(ServerAddr)=SOCKET_ERROR) /綁定socket和本地地址showmess("綁定錯(cuò)誤!n");return; /顯示正在偵聽 showmess("listening.");listen(sock,1);flag=0; /未連接之前,flag=0mydlg=this->GetSafeHwnd(); /取得窗口句柄供線程函數(shù)使用stopbutton=:GetDlgItem(mydlg,IDC_BUTT
20、ON_STOP); /取得關(guān)閉連接按/鈕的句柄供線程函數(shù)使用 AfxBeginThread(WaitForAccept,NULL); /啟動(dòng)WaitForAccept線程等待連接 return; void CServerDlg:showmess(char *mess) /用來在信息窗口顯示信息 m_strmess+=mess; m_strmess+="rn" /在每條信息后添加回車UpdateData(false); /更新信息顯示 flag=0; /將
21、連接標(biāo)志清零strcpy(buff,"end"); send(sockuse,buff,strlen(buff),0); /給對(duì)方發(fā)送信息告知結(jié)束TerminateThread(mainthread->m_hThread,0x01); /結(jié)束MainControl線程closesocket(sock); /關(guān)閉套接字closesocket(sockuse);WSACleanup(); /清理網(wǎng)絡(luò) m_ctrlstop.EnableWindow(false); /使能一些按鈕m_ctrlfile.EnableWindow(false);m_ctrlstart.Enabl
22、eWindow(true); void CServerDlg:OnMyMessage() showmess(buff); /僅僅是為了線程函數(shù)調(diào)用內(nèi)部的信息顯示函數(shù) void CServerDlg:OnButtonFile() flag=0; /設(shè)定 flag TerminateThread(mainthread->m_hThread,0x01); /中止MainControlAfxBeginThread(FileTrans,NULL); /啟用FileTrans線程 void CServerDlg:OnButtonS
23、end() char talkbuff100;memset(talkbuff,0,100);UpdateData(true);strcpy(talkbuff,m_strtalk); /取得對(duì)話框數(shù)據(jù)send(sockuse,talkbuff,100,0); /發(fā)送給對(duì)方信息 clientDlg.cpp 首先是clientDlg.cpp #include "winsock.h" #include "stdio.h"#include"string.h"#pragm
24、a comment(lib,"wsock32.lib") /這四句要加在本文件的開頭部分。保證/網(wǎng)絡(luò)功能正常在BEGIN_MESSAGE_MAP下面要添加ON_MESSAGE(WM_UpdateDATA, OnMyMessage) /*綁定我自己的消息,這樣外部的線程就可以通過SendMessage來調(diào)用窗體的函數(shù)OnMyMessage了,用來顯示信息 WM_UpdateDATA在stdafx.h中我自己定義為#define WM_UpdateDATA WM_USER+100 /定義一個(gè)自己的消息*/ /定義全局變量,方便各個(gè)工
25、作線程和窗口線程的通信SOCKET sock;char buff100; /主要的緩沖區(qū),顯示數(shù)據(jù)使用,也供線程間通信使用HWND mydlg; /記錄窗體的句柄sockaddr_in ServerAddr;int flag=0; /主要是用來標(biāo)志是否連接,用來控制一些循環(huán)和功能CWinThread* mainthread;HWND stopbutton; /記錄關(guān)閉連接按鈕的句柄 UINT WaitForConnect(LPVOID pParam) /等待connect 的線程 if(connect(sock,(struct sockaddr*)&
26、amp;ServerAddr,sizeof(ServerAddr)=SOCKET_ERROR)strcpy(buff,"connect failn");SendMessage(mydlg,WM_UpdateDATA,NULL,NULL); /發(fā)送給窗口消/息,顯示信息closesocket(sock); /失敗則關(guān)閉sockreturn 0;strcpy(buff,"已經(jīng)連接!");SendMessage(mydlg,WM_UpdateDATA,NULL,NULL);/發(fā)送給窗口消/息,顯示信息flag=1;mainthread=AfxBeginThre
27、ad(MainControl,NULL); /建立MainControl線程return 0; char sendbuff100; /發(fā)送緩沖區(qū)char recvbuff100; /接受緩沖區(qū)int num; /記錄每次接受的字節(jié)數(shù) CString szGetName;CFileDialog * lpszOpenFile; /定義一個(gè)CfileDialog對(duì)象lpszOpenFile = new CFileDialog(false,"","",OFN_FILEMUSTEXIST|OFN_HIDEREADONLY,"文件類型
28、(*.*)|*.*|");/生成一個(gè)對(duì)話框if(lpszOpenFile->DoModal()=IDOK)/假如點(diǎn)擊對(duì)話框確定按鈕szGetName = lpszOpenFile->GetPathName(); /得到打開文件的路徑/SetWindowText(szGetName); /在窗口標(biāo)題上顯示路徑delete lpszOpenFile; /釋放分配的對(duì)話框 memset(sendbuff,0,100); strcpy(sendbuff,"sendagree"); send(sock,sendbuff,strlen(sendbuff)
29、,0); /發(fā)送sendagree告知對(duì)方開始發(fā)送吧 SendMessage(mydlg,WM_UpdateDATA,NULL,NULL); /發(fā)送給窗口消息,顯示信息 num=recv(sock,recvbuff,100,0); /接收數(shù)據(jù)FILE *fp=fopen(szGetName,"wb"); /打開文件,路徑為szGetNamefwrite(recvbuff,num,1,fp); /寫入之前的數(shù)據(jù) while(num=100) /根據(jù)接收是否為100字節(jié)判斷文件是否結(jié)束 num=recv(sock,recvbuff,100,0)
30、; fwrite(recvbuff,num,1,fp); strcpy(buff,"接收完畢");SendMessage(mydlg,WM_UpdateDATA,NULL,NULL); /發(fā)送給窗口消息,顯示信息return 0; char recvbuff100;/接受緩沖區(qū) memset(buff,0,100); while(flag) memset(recvbuff,0,100); /每次接收前清空緩沖區(qū) recv(sock,recvbuff,100,0); /進(jìn)行阻塞接收數(shù)據(jù),如果不是用單獨(dú)的線程/
31、會(huì)造成程序假死,這也就是為什么我的程序使用單獨(dú)的線程來處理 if(!strcmp(recvbuff,"end") /消息判斷為end則調(diào)用/窗口的OnButtonEnd函數(shù)來結(jié)束連接的清理工作。SendMessage(stopbutton,BM_CLICK,NULL,NULL); return 0;else if(!strcmp(recvbuff,"sendstart")/接受的消息判斷為"sendstart"則調(diào)用FileRecv() FileRecv();memset(recvbuff,0,100); else strcpy(bu
32、ff,"server:");strcat(buff,recvbuff);SendMessage(mydlg,WM_UpdateDATA,NULL,NULL); /發(fā)送給窗口消息,顯示信息return 0; OPENFILENAMEA ofn; char szFile260; char path260; char filebuff100; int num; ZeroMemory(&ofn, sizeof(ofn); ofn.lStructSize = sizeof(ofn); ofn.hwndOwner = NULL; ofn.lpstrFile = sz
33、File; ofn.lpstrFile0 = '0' ofn.nMaxFile = sizeof(szFile); ofn.lpstrFilter = "所有文件*.*0" ofn.nFilterIndex = 1; ofn.lpstrFileTitle = NULL; ofn.nMaxFileTitle = 0; ofn.lpstrInitialDir = NULL; ofn.Flags = 0; /以上的定義是為了建立一個(gè)文件打開對(duì)話框。步驟/上來說都是固定的,這里只是借用一下 if (GetOpenFileNameA(&ofn)=
34、FALSE) /判斷文件路徑取得是否正確 /若失敗則恢復(fù)建立MainControl線程,進(jìn)行數(shù)據(jù)接收處理。 mainthread=AfxBeginThread(MainControl,NULL); flag=1; /設(shè)定flag保證MainControl可以正常進(jìn)行循環(huán)return 0; memset(filebuff,0,100); /清空filebuff strcpy(path,ofn.lpstrFile); /將路徑拷貝到path中 strcpy(filebuff,"sendstart"); send(sock,filebuff,strlen(filebu
35、ff),0); /發(fā)送請(qǐng)求信息 recv(sock,filebuff,100,0); /等待接收反饋信息 if(strcmp(filebuff,"sendagree") /若接收到的信息不是sendagree strcpy(buff,"對(duì)方接受錯(cuò)誤"); SendMessage(mydlg,WM_UpdateDATA,NULL,NULL); /發(fā)送給窗口消息,顯示信息 mainthread=AfxBeginThread(MainControl,NULL); /恢復(fù)建立MainControl線程 flag=1; /設(shè)定flag保證MainControl循環(huán)
36、正常 return 0; strcpy(buff,"對(duì)方已經(jīng)同意,開始發(fā)送文件"); SendMessage(mydlg,WM_UpdateDATA,NULL,NULL); /發(fā)送給窗口消息,顯示信息 FILE *fp=fopen(path,"rb"); /打開文件 while(!feof(fp) num=fread(filebuff,1,100,fp); /文件結(jié)束前每次讀取100字節(jié) send(sock,filebuff,num,0); /發(fā)送,最后一次不足100字節(jié) /
37、作為標(biāo)志,可以讓接受方知道文件結(jié)束 strcpy(buff,"發(fā)送完畢");SendMessage(mydlg,WM_UpdateDATA,NULL,NULL); /發(fā)送給窗口消息,顯示信息memset(buff,0,100);fclose(fp); /關(guān)閉文件 mainthread=AfxBeginThread(MainControl,NULL); /恢復(fù)建立MainControl線程 flag=1; return 0; m_ctrlstop.EnableWindow(true);m_ctrlfile.EnableWindow(true);m_ctrlconn
38、ect.EnableWindow(false);/以上使各個(gè)按鈕進(jìn)行使能 WSADATA WSAData;/開始建立socket if(WSAStartup(MAKEWORD(2,2),&WSAData)!=0)showmess("socket初始化錯(cuò)誤");return; sock=socket(AF_INET,SOCK_STREAM,0);/采用流式套接字,ipv4 if(sock=SOCKET_ERROR)showmess("SOCK Create FAIL!");WSACleanup
39、(); return;ServerAddr.sin_family = AF_INET;ServerAddr.sin_port = htons(2006);/使用2006端口UpdateData(true); /讀取ip 值ServerAddr.sin_addr.s_addr = inet_addr(m_strip);/使用編輯框中的ip地址,默認(rèn)值 /取得窗口句柄供線程函數(shù)使用flag=0;stopbutton=:GetDlgItem(mydlg,IDC_BUTTON_STOP);/取得關(guān)閉連接按鈕的句柄供線程函數(shù)使用AfxBeginThread(WaitForConn
40、ect,NULL);/啟動(dòng)WaitForConnect線程進(jìn)行連接return; m_strmess+=mess;m_strmess+="rn" /在每條信息后添加回車UpdateData(false); /更新信息顯示 void CClientDlg:OnMyMessage() showmess(buff);/僅僅是為了線程函數(shù)調(diào)用內(nèi)部的信息顯示函數(shù) TerminateThread(mainthread,0x01);/結(jié)束MainControl線程strcpy(buff,"end");send(sock,buff,strlen(buff),0);/給對(duì)方發(fā)送信息告知結(jié)束closesocket(sock);/關(guān)閉套接字 WSACleanup();m_ctrlstop.EnableWindow(false);/使一些按鈕m_ctrlfile.EnableWindow(false);m_ctrlconnect.EnableWindow(true);
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 七年級(jí)生物上冊(cè)第一單元我們身邊的生命世界第二章生物體的結(jié)構(gòu)層次1.2.2細(xì)胞分化形成組織課時(shí)訓(xùn)練含解析新版冀教版
- 二年級(jí)數(shù)學(xué)上冊(cè)三小制作角的初步認(rèn)識(shí)銳角和鈍角的認(rèn)識(shí)教學(xué)設(shè)計(jì)青島版六三制
- 出版印刷合同范例
- 上海市高中政治第六課國家統(tǒng)一民族團(tuán)結(jié)知識(shí)要求與訓(xùn)練滬教版政治常識(shí)
- 個(gè)人汽車過戶合同范例
- 2025年精密過濾輸液器項(xiàng)目發(fā)展計(jì)劃
- 2003專用合同范例
- 修水渠勞務(wù)合同范例
- 農(nóng)場樂園采購合同范本
- 農(nóng)業(yè)股東協(xié)議合同范例
- 第三方單位考核管理辦法
- 造粒塔外壁清洗施工方案
- 鋼棧橋計(jì)算書(excel版)
- MTBE裂解工藝交流材料
- 中醫(yī)診斷學(xué)第七章第二節(jié)六經(jīng)辨證
- 租賃合同審批表
- 數(shù)據(jù)庫及其應(yīng)用-重點(diǎn)復(fù)習(xí)資料.代碼02120
- 巖石堅(jiān)固性和穩(wěn)定性分級(jí)表
- 律師事務(wù)所函[]第號(hào)
- 物流經(jīng)典游戲啤酒游戲(完全操作版)
- 新形勢下如何做一名合格的鄉(xiāng)鎮(zhèn)干部之我見
評(píng)論
0/150
提交評(píng)論