版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、 java程序設(shè)計(jì) 課程設(shè)計(jì)報(bào)告課 題: 基于udp通信的聊天程序 姓 名: 湯 欽 磊 學(xué) 號(hào): 200817010215 同組姓名: 李才偉 專(zhuān)業(yè)班級(jí): 計(jì)科09101 指導(dǎo)教師: 劉國(guó)清老師 設(shè)計(jì)時(shí)間: 評(píng)閱意見(jiàn):評(píng)定成績(jī): 指導(dǎo)老師簽名: 年 月 日 基于udp通信的聊天程序1 協(xié)議介紹和使用說(shuō)明1.1 協(xié)議內(nèi)容本課程設(shè)計(jì)主要是基于udp的并用java實(shí)現(xiàn)的簡(jiǎn)單的聊天程序。udp 用戶(hù)數(shù)據(jù)報(bào)是在運(yùn)輸層的端到端抽象的邏輯信道中傳送的。udp 在傳送數(shù)據(jù)之前不需要先建立連接。對(duì)方的運(yùn)輸層在收到 udp 報(bào)文后,不需要給出任何確認(rèn)。雖然 udp 不提供可靠交付,但在某些情況下 udp 是一種
2、最有效的工作方式。雖然udp 用戶(hù)數(shù)據(jù)報(bào)只能提供不可靠的交付,但 udp 在某些方面有其特殊的優(yōu)點(diǎn),它有即時(shí)通信的功能。比如說(shuō),使用聊天程序聊天的時(shí)候,省去的了跟對(duì)方通信的時(shí)候的鏈接的麻煩,直接進(jìn)行通信。udp 只在 ip 的數(shù)據(jù)報(bào)服務(wù)之上增加了很少一點(diǎn)的功能,即端口的功能和差錯(cuò)檢測(cè)的功能。udp 使用盡最大努力交付,即不保證可靠交付,同時(shí)也不使用擁塞控制。udp 是面向報(bào)文的。udp 沒(méi)有擁塞控制,很適合多媒體通信的要求。udp 支持一對(duì)一、一對(duì)多、多對(duì)一和多對(duì)多的交互通信。發(fā)送方 udp 對(duì)應(yīng)用程序交下來(lái)的報(bào)文,在添加首部后就向下交付 ip 層。udp 對(duì)應(yīng)用層交下來(lái)的報(bào)文,既不合并,也不
3、拆分,而是保留這些報(bào)文的邊界。應(yīng)用層交給 udp 多長(zhǎng)的報(bào)文,udp 就照樣發(fā)送,即一次發(fā)送一個(gè)報(bào)文。接收方 udp 對(duì) ip 層交上來(lái)的 udp 用戶(hù)數(shù)據(jù)報(bào),在去除首部后就原封不動(dòng)地交付上層的應(yīng)用進(jìn)程,一次交付一個(gè)完整的報(bào)文。1.2 關(guān)鍵技術(shù)1.2.1 服務(wù)器端socket的實(shí)現(xiàn)socket又稱(chēng)作套接字,它是使用標(biāo)準(zhǔn)unix文件描述符(filedescriptor)和其它程序通訊的方式。使用send()和recv()讓你更好的控制數(shù)據(jù)傳輸。在java 網(wǎng)絡(luò)編程中,socket相當(dāng)于應(yīng)用程序的港口碼頭;在計(jì)算機(jī)網(wǎng)絡(luò)中,套接字由ip地址和端口號(hào)組成,為進(jìn)程之間通信提供地址。兩個(gè)主機(jī)進(jìn)行通信實(shí)際上
4、就是兩個(gè)主機(jī)中的應(yīng)用進(jìn)程互相通信,應(yīng)用進(jìn)程之間的通信又稱(chēng)為端到端的通信。為應(yīng)用進(jìn)程之間的通信提供運(yùn)輸服務(wù)的是運(yùn)輸層的運(yùn)輸協(xié)議,運(yùn)輸層需要有兩種不同的運(yùn)輸協(xié)議,即面向連接的tcp和無(wú)連接的udp。 在java中,用于實(shí)現(xiàn)基于udp的聊天程序,使用兩個(gè)重要的類(lèi)(datagramsocket類(lèi)和datagrampacket類(lèi))。datagramsocket類(lèi)表示用來(lái)發(fā)送和接收數(shù)據(jù)報(bào)包的套接字。數(shù)據(jù)報(bào)套接字是包投遞服務(wù)的發(fā)送或接收點(diǎn)。每個(gè)在數(shù)據(jù)報(bào)套接字上發(fā)送或接收的包都是單獨(dú)編址和路由的。從一臺(tái)機(jī)器發(fā)送到另一臺(tái)機(jī)器的多個(gè)包可能選擇不同的路由,也可能按不同的順序到達(dá)。 在datagramsocket上總
5、是啟用udp廣播發(fā)送。為了接收廣播包,應(yīng)該將 datagramsocket綁定到通配符地址。在某些實(shí)現(xiàn)中,將datagramsocket綁定到一個(gè)更加具體的地址時(shí)廣播包也可以被接收。atagrampacket類(lèi)表示數(shù)據(jù)報(bào)包。 數(shù)據(jù)報(bào)包用來(lái)實(shí)現(xiàn)無(wú)連接包投遞服務(wù)。每條報(bào)文僅根據(jù)該包中包含的信息從一臺(tái)機(jī)器路由到另一臺(tái)機(jī)器。從一臺(tái)機(jī)器發(fā)送到另一臺(tái)機(jī)器的多個(gè)包可能選擇不同的路由,也可能按不同的順序到達(dá)。不對(duì)包投遞做出保證。服務(wù)程序工作在服務(wù)器的某個(gè)端口上,一旦啟動(dòng)服務(wù),它將在這個(gè)端口上監(jiān)聽(tīng),等待客戶(hù)程序發(fā)來(lái)請(qǐng)求,當(dāng)有客戶(hù)連接到該端口,accept()方法就返回一個(gè)socket對(duì)象,可以用該對(duì)象獲得一個(gè)輸
6、入輸出流。服務(wù)器的套接字用服務(wù)器套接字類(lèi)(serversocket)來(lái)建立。具體實(shí)現(xiàn)如下:(1)建立一個(gè)服務(wù)者,端口為5000。(2)服務(wù)者永遠(yuǎn)等待,一旦客戶(hù)送來(lái)正確的請(qǐng)求,連接至該端口,accept()方法就返回一個(gè)socket對(duì)象。(3)用返回的socket對(duì)象創(chuàng)建數(shù)據(jù)輸入流類(lèi)的實(shí)例in。用返回的socket對(duì)象創(chuàng)建數(shù)據(jù)輸出流的實(shí)例out。以上實(shí)例in和out是服務(wù)者用于從客戶(hù)接受輸入信息和向客戶(hù)程序發(fā)送信息所用。此外,還需要用方法readline()和println()讀取或輸出一行數(shù)據(jù)。(4)soc.close()關(guān)閉socket。1.2.2 通信的建立在客戶(hù)端建立socket對(duì)象,并
7、進(jìn)行異常處理,主機(jī)名和端口號(hào)與連接的服務(wù)器名和提供該服務(wù)的服務(wù)程序的監(jiān)聽(tīng)端口必須一致。建立連接后用socket類(lèi)提供的getinputstream()和getoutputstream()方法取得輸入輸出流。在服務(wù)器端,獲得的輸入流是客戶(hù)端的輸出流,而socket獲得的輸出流是發(fā)向客戶(hù)端的輸入流,在客戶(hù)端也是這樣。獲得socket的輸入輸出流之后,為了便于讀寫(xiě)操作,需要在這兩個(gè)流對(duì)象基礎(chǔ)上建立易于操作的數(shù)據(jù)流dateinputstream, dataoutputstream。然后對(duì)輸入輸出流進(jìn)行讀寫(xiě)操作。在通信結(jié)束時(shí)關(guān)閉socket,以斷開(kāi)連接,釋放資源。先關(guān)閉對(duì)應(yīng)的輸入輸出流,再關(guān)閉socke
8、t本身。1.2.2 數(shù)據(jù)庫(kù)的建立mysql數(shù)據(jù)庫(kù):2 程序設(shè)計(jì)2.1系統(tǒng)結(jié)構(gòu)本系統(tǒng)采用一個(gè)服務(wù)器端和多個(gè)客戶(hù)端的聊天方式來(lái)實(shí)現(xiàn)。結(jié)構(gòu)圖如下所示:圖2.1服務(wù)器-客戶(hù)端結(jié)構(gòu)圖2.2主程序設(shè)計(jì)2.2.1 服務(wù)器端程序 服務(wù)器與客戶(hù)間通過(guò)套接口socket連接。在java中使用套接口相當(dāng)簡(jiǎn)單,java api為處理套接口的通信提供了一個(gè)類(lèi).socket.,使得編寫(xiě)網(wǎng)絡(luò)應(yīng)用程序相對(duì)容易服務(wù)器采用多線(xiàn)程以滿(mǎn)足多用戶(hù)的請(qǐng)求,程序用vector向量數(shù)組存儲(chǔ)連接客戶(hù)變量,通過(guò)創(chuàng)建一個(gè)serversocket對(duì)象來(lái)監(jiān)聽(tīng)來(lái)自客戶(hù)的連接請(qǐng)求,默認(rèn)端口為2012,然后無(wú)限循環(huán)調(diào)用accept()方法接受客戶(hù)程序的連接
9、。2.2.2 客戶(hù)端程序 圖2.2主程序流程圖2.3 各模塊設(shè)計(jì)2.3.1客戶(hù)端向服務(wù)器發(fā)送消息 服務(wù)器與客戶(hù)都通過(guò)datagramsocket 以任意端口發(fā)送,datagrampacket以2012端口來(lái)接收信息,信息從文本框輸輸入,一旦收到客戶(hù)方的連接請(qǐng)求,服務(wù)器accept()方法返回一個(gè)新建的socket對(duì)象。客戶(hù)端然后向服務(wù)器發(fā)送消息, 2.3.2客戶(hù)端之間發(fā)送消息 客戶(hù)間發(fā)送信息通過(guò)udp來(lái)實(shí)現(xiàn),用戶(hù)登錄時(shí)通過(guò)類(lèi)datagrampacket和datagramsocket創(chuàng)建udp包括其本地接受端口以及發(fā)送端口,默認(rèn)端口為2012,通過(guò)取得的好友的ip地址來(lái)向好友發(fā)送消息(send(
10、datagrampacket)和接受消息(receive(datagrampacket)。 2.4 界面設(shè)計(jì)2.4.1 界面設(shè)計(jì)的方法在frame布局容器中,添加一個(gè)顯示聊天的文本框(在上面),在加入panel面板,panel面板中包括三個(gè)textfield單行文本框。 圖2.3界面實(shí)現(xiàn)功能圖2.4.2 界面的功能 界面中的組件有三個(gè)輸入框,一個(gè)文本框,兩個(gè)按鈕。輸入框要輸入服務(wù)器的、用戶(hù)名和要發(fā)送的聊天內(nèi)容。文本框顯示所以聊天人已經(jīng)發(fā)送的聊天內(nèi)容。按鈕有連接按鈕和發(fā)送按鈕。服務(wù)器端只顯示連接的建立、用戶(hù)進(jìn)入和退出、連接釋放。2.5 實(shí)現(xiàn)代碼實(shí)現(xiàn)通信的代碼:package com.lcw.ud
11、p;import java.awt.font;import java.awt.event.*;import java.io.bufferedwriter;import java.io.file;import java.io.filewriter;import java.io.ioexception;import .*;import javax.swing.*;public class udpnetchat extends jframe implements runnableprivate static final long serialversionuid = 1l;jlabel lab,la
12、b1,lab2;jtextfield tx,tx1,tx2;jbutton but,but1,but2;jtextarea txa;public udpnetchat()this.setlayout(null);/=lab=new jlabel(本機(jī)ip);lab.setbounds(10,0,60,30);this.add(lab);tx=new jtextfield(,20);tx.setbounds(75, 0, 200, 30);string adstr;try inetaddress addr=inetaddress.getlocalhost();int index=addr.tos
13、tring().indexof(/);adstr=addr.tostring().substring(index+1);tx.settext(adstr); catch (unknownhostexception e) e.printstacktrace();this.add(tx);lab1=new jlabel(對(duì)方ip);lab1.setbounds(10, 30, 60, 30);this.add(lab1);lab2=new jlabel(發(fā)言:);lab2.setbounds(10, 70, 60, 30);this.add(lab2);tx1=new jtextfield(,20
14、);tx1.setbounds(75, 30, 200, 30);/tx1.settext(172.16.92.79);this.add(tx1);tx2=new jtextfield();tx2.setbounds(75, 70, 300, 30);this.add(tx2);but=new jbutton(發(fā)送);but.setbounds(380, 70, 80, 30);but.setmnemonic(keyevent.vk_enter);but.addmouselistener(new mymouselistener();this.add(but);txa=new jtextarea
15、();font font = new font(宋體, font.plain, 14);txa.setfont(font);txa.setbounds(15, 110, 450, 300);this.add(txa);but1=new jbutton(保存聊天記錄);but1.addactionlistener(new actionlistener()public void actionperformed(actionevent e) try string filename = joptionpane.showinputdialog(輸入保存的文件名及所在路徑);file file = new
16、 file(filename);bufferedwriter bw = new bufferedwriter(new filewriter(file);bw.write(txa.gettext().tostring();bw.close(); catch (exception ce) ce.printstacktrace(););but1.setbounds(30,430,150,30);but2=new jbutton(退出聊天);but2.setbounds(200, 430, 150, 30);/退出聊天but2.addactionlistener(new actionlistener(
17、)public void actionperformed(actionevent e) dispose(););this.add(but1);this.add(but2);/=this.settitle(基于udp的網(wǎng)絡(luò)聊天程序);this.setbounds(100, 100, 480, 550);this.setvisible(true);public void run() /接收數(shù)據(jù)while(true)/持續(xù)接收本地端的信息byte buf=new byte100;/預(yù)期最多可收100個(gè)bytetrydatagramsocket ds=new datagramsocket(2012);
18、/用2222 port 收datagrampacket dp=new datagrampacket(buf,buf.length);/將數(shù)據(jù)收到buf數(shù)組ds.receive(dp);tx1.settext(dp.getaddress().gethostaddress();txa.append(來(lái)自+dp.getaddress().gethostaddress()+:+dp.getport()+new string(buf).trim()+n); /此處用new string(dp.getdata().trim()也一樣ds.close();thread.sleep(200);catch(in
19、terruptedexception e)catch(socketexception e)catch(ioexception e)class mymouselistener extends mouseadapter/送數(shù)據(jù)public void mouseclicked(mouseevent e)/每次click按鈕就發(fā)送信息到目的端主機(jī)string msg=tx2.gettext().trim();string ipstr=tx1.gettext().trim();trydatagramsocket ds=new datagramsocket();/以任一目前可用的port送datagram
20、packet dp=new datagrampacket(msg.getbytes(),msg.getbytes().length,inetaddress.getbyname(ipstr),2012);/送到遠(yuǎn)程的2012 portds.send(dp);/送出數(shù)據(jù)包txa.append(我說(shuō):+msg.trim()+n);/給自己看的記錄ds.close();catch(socketexception e1)catch(ioexception e1)客戶(hù)端注冊(cè)代碼:package com.lcw.udp;import java.awt.*;import java.awt.event.*;im
21、port java.sql.*;import javax.swing.*;public class register extends jframe /* * param args */public static void main(string args) register frame=new register();frame.setdefaultcloseoperation(jframe.exit_on_close);frame.setvisible(true);jtextfield tx1;jpasswordfield psd1,psd2;public register()this.set
22、size(300,150);this.settitle(新用戶(hù)注冊(cè));container c=getcontentpane();jpanel panel=new jpanel();panel.setlayout(new gridlayout(3,2);jlabel lab1,lab2,lab3;lab1=new jlabel(賬號(hào));lab2=new jlabel(密碼);lab3=new jlabel(確認(rèn)密碼);tx1=new jtextfield();psd1=new jpasswordfield();psd2=new jpasswordfield();panel.add(lab1);p
23、anel.add(tx1);panel.add(lab2);panel.add(psd1);panel.add(lab3);panel.add(psd2);c.add(panel,borderlayout.center);jpanel pan=new jpanel();jbutton but1,but2,but3;but1=new jbutton(注冊(cè));but2=new jbutton(重置);but3=new jbutton(直接登陸);/but1按鈕事件處理but1.addactionlistener(new actionlistener()public void actionperfo
24、rmed(actionevent e) string id=tx1.gettext().trim().tostring();suppresswarnings(deprecation)string pasd1=psd1.gettext().tostring();suppresswarnings(deprecation)string pasd2=psd2.gettext().tostring();if(pasd1.equalsignorecase(pasd2)tryclass.forname(com.mysql.jdbc.driver);string url=jdbc:mysql:/localho
25、st:3306/user;connection conn=drivermanager.getconnection(url,root,root);statement stmt=conn.createstatement();string sql=insert into t_user values(+id+,+pasd1+);resultset rs=stmt.executequery(select *from t_user);/*若譔賬號(hào)已存在,則需要重新注冊(cè)*/while(rs.next()if(rs.getstring(id).equals(id)joptionpane.showmessage
26、dialog(null, 該賬號(hào)已被注冊(cè),請(qǐng)重新注冊(cè)!);elseint num=stmt.executeupdate(sql);if(num0)joptionpane.showmessagedialog(null, 恭喜您注冊(cè)成功!);stmt.close();conn.close();catch(exception ce)ce.printstacktrace(););/but2按鈕事件處理but2.addactionlistener(new actionlistener()public void actionperformed(actionevent e) tx1.settext();ps
27、d1.settext();psd2.settext(););/but3按鈕事件處理but3.addactionlistener(new actionlistener()public void actionperformed(actionevent e) login log=new login();dispose(););pan.add(but1);pan.add(but2);pan.add(but3);c.add(pan,borderlayout.south);客戶(hù)端登錄代碼:package com.lcw.udp;import java.awt.*;import java.awt.event
28、.*;import javax.swing.*;import java.sql.*;public class login extends jframe/* * param args */jtextfield tx1;jpasswordfield psd1;public login()this.setvisible(true);this.setsize(300,150);this.settitle(用戶(hù)登陸);container c=getcontentpane();jpanel panel=new jpanel();panel.setsize(300,80);panel.setlayout(n
29、ew gridlayout(2,2);jlabel lab1,lab2;lab1=new jlabel(賬號(hào));lab2=new jlabel(密碼);tx1=new jtextfield();psd1=new jpasswordfield();panel.add(lab1);panel.add(tx1);panel.add(lab2);panel.add(psd1);c.add(panel,borderlayout.center);jpanel pan=new jpanel();jbutton but1,but2;but1=new jbutton(登陸);but2=new jbutton(重
30、置);/but1按鈕事件處理but1.addactionlistener(new actionlistener() public void actionperformed(actionevent e) string id = tx1.gettext().trim().tostring();suppresswarnings(deprecation)string pasd1 = psd1.gettext().tostring();string driver = com.mysql.jdbc.driver;string url = jdbc:mysql:/localhost:3306/user;tr
31、y class.forname(driver);connection conn = drivermanager.getconnection(url, root,root);statement stmt = conn.createstatement();resultset rs=stmt.executequery(select *from t_user);while(rs.next()if(rs.getstring(id).equals(id)&rs.getstring(pwd).equalsignorecase(pasd1)udpnetchat form1 = new udpnetchat()
32、;thread threadobj = new thread(form1);threadobj.start();/ 啟動(dòng)接收消息的線(xiàn)程dispose();/*elsejoptionpane.showmessagedialog(null, 用戶(hù)名或密碼錯(cuò)誤!);*/ catch (exception ce) ce.printstacktrace(););/but2按鈕事件處理but2.addactionlistener(new actionlistener() public void actionperformed(actionevent e) tx1.settext();psd1.settex
33、t(););pan.add(but1);pan.add(but2);c.add(pan,borderlayout.south);2.6 程序調(diào)試及運(yùn)行結(jié)果2.6.1 調(diào)試前的準(zhǔn)備 安裝jdk1.6.0并在計(jì)算機(jī)的環(huán)境變量中配置好java環(huán)境。使用的實(shí)驗(yàn)環(huán)境是windows xp,eclipse 6.0,。使用2臺(tái)主機(jī)進(jìn)行通信,一臺(tái)作為服務(wù)器,一臺(tái)作為客戶(hù)端。2.6.2 程序調(diào)試過(guò)程 啟動(dòng)eclipse首先在一臺(tái)主機(jī)上運(yùn)行服務(wù)器端程序,再在另外一臺(tái)機(jī)器上運(yùn)行客戶(hù)端程序。然后進(jìn)入到用戶(hù)的圖形用戶(hù)界面,輸入客戶(hù)端的ip,進(jìn)行連接,如果連接成功,則客戶(hù)端就可以通過(guò)與服務(wù)器端進(jìn)行通信,然后服務(wù)器轉(zhuǎn)發(fā)通信,實(shí)現(xiàn)了兩個(gè)客戶(hù)端之間的聊天功能。2.6.3 程序運(yùn)行結(jié)果該結(jié)果是在同一機(jī)器上運(yùn)行結(jié)果:2.6.4 出錯(cuò)分析 在主機(jī)2的聊天窗口中第二行出現(xiàn)亂碼,經(jīng)檢查是由于中文編碼出現(xiàn)問(wèn)題,而英文字符可以正確傳輸。在接受端的字符串的編碼方法強(qiáng)制轉(zhuǎn)換
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
- 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ì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 二零二五年度玻璃幕墻工程節(jié)能認(rèn)證施工合同范本3篇
- 二零二五年度城市道路照明設(shè)施承包合同樣本2篇
- 二零二五年度環(huán)保設(shè)施承攬工程合同范本2篇
- 2025年加盟鐘表店合同
- 民間個(gè)人擔(dān)保借款合同書(shū)
- 天文觀測(cè)數(shù)據(jù)結(jié)構(gòu)化處理
- 2025年嬰幼兒用品代理合同
- 二零二五版環(huán)保節(jié)能門(mén)頭照明系統(tǒng)合同4篇
- 二零二五版美甲店會(huì)員積分體系合作合同4篇
- 2025年魯科五四新版九年級(jí)地理上冊(cè)階段測(cè)試試卷
- 河南省濮陽(yáng)市2024-2025學(xué)年高一上學(xué)期1月期末考試語(yǔ)文試題(含答案)
- 割接方案的要點(diǎn)、難點(diǎn)及采取的相應(yīng)措施
- 2025年副護(hù)士長(zhǎng)競(jìng)聘演講稿(3篇)
- 2024年08月北京中信銀行北京分行社會(huì)招考(826)筆試歷年參考題庫(kù)附帶答案詳解
- 原發(fā)性腎病綜合征護(hù)理
- (一模)株洲市2025屆高三教學(xué)質(zhì)量統(tǒng)一檢測(cè) 英語(yǔ)試卷
- 蘇教版二年級(jí)數(shù)學(xué)下冊(cè)全冊(cè)教學(xué)設(shè)計(jì)
- 金字塔原理與結(jié)構(gòu)化思維考核試題及答案
- 基礎(chǔ)護(hù)理學(xué)導(dǎo)尿操作
- DB11∕T 1028-2021 民用建筑節(jié)能門(mén)窗工程技術(shù)標(biāo)準(zhǔn)
- 四川省成都市溫江區(qū)2023-2024學(xué)年四年級(jí)下學(xué)期期末語(yǔ)文試卷
評(píng)論
0/150
提交評(píng)論