版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
聊天室系统青岛科技大学操作系统课程设计学生班级计算机132班学生学号1308010204学生姓名王永远518518182016______年___月___日2016目录设计题目:聊天室系统 3一、设计目的及要求 31.1设计目的 31.2设计要求: 3二、技术背景 32.1网络编程 32.2网络通信 32.3Socket 32.4TCP传输 42.5Java的多线程机制 4三、需求分析 43.1客户端 43.1.1登录 43.1.2多人聊天 43.1.3单人聊天 53.2服务器端 5四、总体设计 54.1设计思想流程图 54.2设计思想分析 6五、详细设计 65.1客户端设计 75.1.1登录界面 75.1.2聊天室界面 75.1.3单人聊天界面 75.2服务器端设计 8六、系统测试 86.1登录测试 86.1.1用户名为英文字母 86.1.2用户名为中文 96.1.3用户名为标点符号 96.1.4多个用户有重名 106.1.5服务器地址不合法 116.1.6端口号不合法 126.1.7服务器未开启 126.2群发消息测试 136.3私聊测试 156.4用户列表显示测试 16七、心得体会 16八、参考资料 16九、程序清单 16设计题目:聊天室系统一、设计目的及要求1.1设计目的通过该聊天室系统,掌握网络编程的概念及基于网络的C/S模式软件系统开发,掌握基于TCP协议的Socket编程,掌握Java的多线程机制。1.2设计要求:实现多个用户之间类似于QQ的聊天程序,有聊天界面,多用户之间既可以实现群聊,也可以单独聊天。二、技术背景2.1网络编程就是用来实现网络互连的不同计算机上运行的程序间可以进行数据交换。2.2网络通信(1)IP地址:网络中设备的标识,不易记忆,可用主机名要想让网络中的计算机能够互相通信,必须为每台计算机指定一个标识号,通过这个标识号来指定要接受数据的计算机和识别发送的计算机,在TCP/IP协议中,这个标识号就是IP地址。(2)端口号:用于标识进程的逻辑地址物理端口网卡口逻辑端口我们指的就是逻辑端口A:每个网络程序都会至少有一个逻辑端口B:用于标识进程的逻辑地址,不同进程的标识C:有效端口:0~65535,其中0~1024系统使用或保留端口。(3)传输协议:通信的规则,常见的有UDP,TCPUDP:将数据源和目的封装成数据包中,不需要建立连接;每个数据报的大小在限制在64k;因无连接,是不可靠协议;不需要建立连接,速度快。TCP:建立连接,形成传输数据的通道;在连接中进行大数据量传输;通过三次握手完成连接,是可靠协议;必须建立连接,效率会稍低。2.3Socket(1)Socket套接字网络上具有唯一标识的IP地址和端口号组合在一起才能构成唯一能识别的标识符套接字。(2)Socket原理机制A:通信的两端都有Socket。B:网络通信其实就是Socket间的通信。C:数据在两个Socket间通过IO传输。2.4TCP传输(1)客户端思路A建立客户端的Socket服务,并明确要连接的服务器。B如果连接建立成功,就表明,已经建立了数据传输的通道.就可以在该通道通过IO进行数据的读取和写入.该通道称为Socket流,Socket流中既有读取流,也有写入流.C通过Socket对象的方法,可以获取这两个流D通过流的对象可以对数据进行传输E如果传输数据完毕,关闭资源(2)服务器端思路A建立服务器端的socket服务,需要一个端口B服务端没有直接流的操作,而是通过accept方法获取客户端对象,在通过获取到的客户端对象的流和客户端进行通信C通过客户端的获取流对象的方法,读取数据或者写入数据D如果服务完成,需要关闭客户端,然后关闭服务器,但是,一般会关闭客户端,不会关闭服务器,因为服务端是一直提供服务的2.5Java的多线程机制进程:每个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销,一个进程包含1--n个线程。线程:同一类线程共享代码和数据空间,每个线程有独立的运行栈和程序计数器(PC),线程切换开销小。多进程是指操作系统能同时运行多个任务(程序),多线程是指在同一程序中有多个顺序流在执行。在java中,每次程序运行至少启动2个线程。一个是main线程,一个是垃圾收集线程。因为每当使用java命令执行一个类的时候,实际上都会启动一个JVM,启动JVM实际上就是在操作系统中启动了一个进程。在java中所有的线程都是同时启动的,至于什么时候,哪个先执行,完全看谁先得到CPU的资源。三、需求分析实现聊天的功能,采用Java
Socket编程,服务器与客户端采用了TCP/IP连接方式,在设计聊天方案时,可将所有信息发往服务器端,再由服务器进行处理,服务器端是所有信息的中心。3.1客户端3.1.1登录用户需要填写用户名、服务器地址、端口号才可以进入聊天室与在线用户聊天,此外,服务器地址默认是本机地址,端口号默认是5000。用户名可以中文,英文字母或标点符号,服务器地址必须是符合点分十进制的合法地址,端口号可以修改,但服务器端程序内默认端口号也必须修改。该聊天室不需要注册,直接登录即可聊天,退出后,系统不保留用户任何信息。若新登录用户与在线用户的用户名重名,则系统会自动修改用户名。格式为:用户名+“_客户端线程ID”。3.1.2多人聊天每个在线用户都可以发送聊天信息,服务器端会一直监听,并把每一个在线用户发送的聊天信息转发到每一个客户端。聊天室的聊天信息格式为:用户名时间(yyyy-MM-ddHH:mm:ss)聊天信息3.1.3单人聊天用户可以选择某一个在线用户实现单人聊天,该聊天信息不会在聊天室显示,只有单聊的两个人能够看到。单人聊天的聊天信息格式为:用户名时间(yyyy-MM-ddHH:mm)聊天信息3.2服务器端服务器端主要处理客户端的请求,包括用户的登录,发送多人聊天信息,退出聊天室,单人聊天请求,发送单人聊天信息,并且随时更新在线用户列表。四、总体设计4.1设计思想流程图4.2设计思想分析首先启动服务器,它会建立一个专门用于接收客户端连接请求的“倾听Socket”,然后等待客户的连接请求。当用户登录输入信息后,与服务器建立Socket连接,服务器端的“倾听Socket”收到连接请求后,会接受连接请求,并生成一个服务器端socket,专门负责与此客户端socket的通信。一旦连接请求成功,客户端将信息及请求通过本方socket的输出流发送给服务器端相应的socket,服务端则通过服务器端Socket的输入流接受客户端传输过来的信息及请求,分析是何请求,然后根据请求类型,进行相应的处理(如登录、私聊等)。服务器端也可以根据需要,通过socket的输出流发送信息和请求给客户端。客户端和服务器端都可以通过关闭本方的socket而结束一次通信过程。对于客户端的各种请求,实际上都是通过在客户端发往服务器的各种字符流区分的,具体的方法就是在消息的内部添加特殊字符串,从而实现服务器对消息请求的识别。比如对于登陆信息,消息中添加的内容就是“@login”,而对于私聊中的消息,消息中添加的内容就是“@single”,其他的同理都添加了相应内容。当然,对于客户端来说,这些都是透明的,用户的操作并没有受到任何影响。在服务器端,消息被检测分析后,变回根据具体的目的进行处理,比如是私聊消息,服务器便会根据其内部添加的信息,向目标端转发该条消息,当目标端接收到连接请求后,会主动建立一个私聊窗口,从而实现私聊。服务器端需要能同时接受多个用户的请求,为了实现这一点,一般使用多线程机制来处理,对每一个客户端连接通信,服务器端都有一个线程专门负责处理。对于客户端的各种请求,内部添加的信息分别如下:@clientThread客户端线程启动messages.add(clientThread.getId()+"@clientThread");客户端线程ID@login登录客户端username+"@login"+getThreadID()+"@login"用户名+客户端线程ID@userlist用户列表serverThread.users.get(newInteger(threadID))+"@userlist"+threadID+"@userlist"用户名+客户端线程ID@chat群聊username+"@chat"+getThreadID()+"@chat"+mess+"@chat"用户名+客户端线程ID+聊天信息@serverexit服务器退出serverThread.messages+"@serverexit"@single单聊client.username+"@single"+client.getThreadID()+"@single"+(int)client.clientuserid.get(index)+"@single"+mess+"@single";用户名+客户端线程ID+客户端线程ID+聊天信息@exit退出群聊username+"@exit"+getThreadID()+"@exit"用户名+客户端线程ID五、详细设计5.1客户端设计5.1.1登录界面5.1.2聊天室界面5.1.3单人聊天界面5.2服务器端设计六、系统测试6.1登录测试6.1.1用户名为英文字母6.1.2用户名为中文6.1.3用户名为标点符号6.1.4多个用户有重名6.1.5服务器地址不合法6.1.6端口号不合法6.1.7服务器未开启6.2群发消息测试6.3私聊测试6.4用户列表显示测试无论已经登录用户的退出,还是新用户成功登录,用户列表显示部分都能正确显示。七、心得体会这段时间通过不断的修改,我终于把聊天室系统完成了,虽然它只有简单的聊天功能,但通过它,我不但巩固了以前学的知识,而且学到了许多在课堂中学不到的知识。通过这次课程设计,我更坚定了理论与实际相结合是十分重要的想法,即使一个人读了再多的技术图书,但没有相关的实践经验,那么他也不会真正地掌握一门技术。只有把理论知识与实践相结合,才会深入的了解并提高自己的独立思考能力。通过这次的课程设计,我将自己所学的Java语言得到了实际的应用,在完成的过程中也遇到了许多困难,但通过不断地查阅资料,最终还是解决了,在这个过程中,我学会了独立思考,同时也让我明白完成一件事情要不断开阔视野,拓展知识面,解放自己的思维。总之,在完成课程设计的过程中,我学会了如何克服开发中遇到的技术困难,学会了独立面对并解决问题。八、参考资料叶核亚JAVA程序设计实用教程(第2版)电子工业出版社朱福喜,路迟JAVA语言与面向对象程序设计武汉大学出版社沈文炎Java高级编程机械工业出版社九、程序清单(1)Client.javapublicclassClientextendsThread{ publicSocketc_socket;//套接字 privateClient_chatFramec_chatFrame;//聊天室聊天界面 privateClient_enterFramec_enterFrame;//客户端登录界面 privateClient_singleFramec_singleFrame;//单人聊天界面 publicDataInputStreamdis=null;//IO输入 publicDataOutputStreamdos=null;//IO输出 privatebooleanflag_exit=false;//客户端未启动标记 privateintthreadID;//聊天室客户端线程标记 publicMap<String,Client_singleFrame>c_singleFrames;//单人聊天,用户名为键,单聊客户端为值 publicList<String>username_online;//在线用户 publicList<Integer>clientuserid;//用户ID publicStringusername=null;//用户名 publicStringchat_re;//通道内相关信息 //getter,setter方法 publicClient_chatFramegetC_chatFrame(){ returnc_chatFrame; } publicClient_singleFramegetC_singlFrame(){ returnc_singleFrame; } publicvoidsetC_singlFrame(Client_singleFramec_singlFrame){ this.c_singleFrame=c_singlFrame; } publicvoidsetC_chatFrame(Client_chatFramec_chatFrame){ this.c_chatFrame=c_chatFrame; } publicClient_enterFramegetC_enterFrame(){ returnc_enterFrame; } publicvoidsetC_enterFrame(Client_enterFramec_enterFrame){ this.c_enterFrame=c_enterFrame; } publicintgetThreadID(){ returnthreadID; } publicvoidsetThreadID(intthreadID){ this.threadID=threadID; } //客户端构造函数 publicClient(){ c_singleFrames=newHashMap<String,Client_singleFrame>(); username_online=newArrayList<String>(); clientuserid=newArrayList<Integer>();// signlechatuse=newArrayList<String>(); } //main方法,设置进入时登录界面 publicstaticvoidmain(String[]args){ Clientclient=newClient(); Client_enterFramec_enterFrame=newClient_enterFrame(client); client.setC_enterFrame(c_enterFrame); c_enterFrame.setVisible(true); } //登录客户端 publicStringlogin(Stringusername,StringhostIp,StringhostPort){ this.username=username;//用户名 Stringlogin_mess=null;//错误信息或true try{ c_socket=newSocket(hostIp,Integer.parseInt(hostPort)); }catch(NumberFormatExceptione){ login_mess="连接的服务器端口号port为整数,取值范围为:1024<port<65535"; returnlogin_mess; }catch(UnknownHostExceptione){ login_mess="主机地址错误"; returnlogin_mess; }catch(IOExceptione){ login_mess="连接服务器失败,请稍后再试"; returnlogin_mess; } return"true"; } //创建一个客户端聊天界面,启动一个线程 publicvoidshowChatFrame(Stringusername){ getDataInit(); c_chatFrame=newClient_chatFrame(this,username); c_chatFrame.setVisible(true); flag_exit=true;//客户端已启动 this.start();//启动线程 } //初始化,建立连接通道 privatevoidgetDataInit(){ try{ dis=newDataInputStream(c_socket.getInputStream()); dos=newDataOutputStream(c_socket.getOutputStream()); }catch(IOExceptione){ e.printStackTrace(); } } //该类声明为Thread的子类,重写Thread类的run方法 publicvoidrun(){ while(flag_exit){//客户端已启动 try{ //readUTF():读入一个已使用UTF-8修改版格式编码的字符串。 chat_re=dis.readUTF(); }catch(IOExceptione){ flag_exit=false; if(!chat_re.contains("@serverexit")){ chat_re=null; } } if(chat_re!=null){ if(chat_re.contains("@clientThread")){ intlocal=chat_re.indexOf("@clientThread"); setThreadID(Integer.parseInt(chat_re.substring(0,local)));//启动客户端线程,设置ThreadID try{ dos.writeUTF(username+"@login"+getThreadID()+"@login"); }catch(IOExceptione){ e.printStackTrace(); } }else{ if(chat_re.contains("@userlist")){ c_chatFrame.setDisUsers(chat_re); }else{ if(chat_re.contains("@chat")){ c_chatFrame.setDisMess(chat_re); }else{ if(chat_re.contains("@serverexit")){ c_chatFrame.closeClient(); }else{ if(chat_re.contains("@single")){ c_chatFrame.setSingleFrame(chat_re); } } } } } } } } //发送聊天信息 publicvoidtransMess(Stringmess){ try{ dos.writeUTF(username+"@chat"+getThreadID()+"@chat"+mess+"@chat"); }catch(IOExceptione){ e.printStackTrace(); } } //聊天室中退出聊天 publicvoidexitChat(){ try{ dos.writeUTF(username+"@exit"+getThreadID()+"@exit"); flag_exit=false; System.exit(0); }catch(IOExceptione){ e.printStackTrace(); } } //登录之前退出 publicvoidexitLogin(){ System.exit(0); } //服务器关闭,退出聊天室客户端,在Client_chatFrame中调用 publicvoidexitClient(){ flag_exit=false; System.exit(0); }}(2)WinCenter.javapublicclassWinCenter{ publicstaticvoidcenter(Windowwin){ Toolkittkit=Toolkit.getDefaultToolkit();//使用系统工具包 DimensionsSize=tkit.getScreenSize();//屏幕尺寸 DimensionwSize=win.getSize();//窗体尺寸 if(wSize.height>sSize.height){ wSize.height=sSize.height; } if(wSize.width>sSize.width){ wSize.width=sSize.width; } win.setLocation((sSize.width-wSize.width)/2,(sSize.height-wSize.height)/2);//窗体居屏幕中央 }}(3)Server.javapublicclassServer{ privateServerFrameserverFrame; privateServerThreadserverThread; publicServerFramegetServerFrame(){ returnserverFrame; } publicvoidsetServerFrame(ServerFrameserverFrame){ this.serverFrame=serverFrame; } publicServer(){} //启动服务器线程 publicvoidstartServer(){ try{ serverThread=newServerThread(serverFrame); }catch(Exceptione){ System.exit(0); } serverThread.setFlag_exit(true); serverThread.start(); } //停止服务器线程 publicvoidstopServer(){ synchronized(serverThread.messages){//同步代码块:synchronized:当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码。 Stringstr="@serverexit"; serverThread.messages.add(str); } serverThread.serverFrame.setDisMess("@exit");//清除聊天信息 serverThread.serverFrame.setDisUsers("@exit");//清除在线用户 serverThread.stopServer();//停止服务器线程 } //main方法 publicstaticvoidmain(String[]args){ Serverserver=newServer(); ServerFrameserverFrame=newServerFrame(server); server.setServerFrame(serverFrame); serverFrame.setVisible(true); } //停止服务器线程并退出 publicvoidclose(){ if(serverThread!=null){ if(serverThread.isAlive()){ serverThread.stopServer(); } } System.exit(0); }}(4)ServerThread.javapublicclassServerThreadextendsThread{ //Vector类可以实现可增长的对象数组。与数组一样,它包含可以使用整数索引进行访问的组件。 //但是,Vector的大小可以根据需要增大或缩小,以适应创建Vector后进行添加或移除项的操作。 publicServerSocketserverSocket;//服务器套接字 publicVector<String>messages;//messages.add(clientThread.getId()+"@clientThread") publicVector<ClientThread>clients;//客户端线程 publicMap<Integer,String>users;//客户端线程ID和用户姓名 publicBroadCastbroadcast; publicintPort=5000; publicbooleanlogin=true; publicServerFrameserverFrame; privatebooleanflag_exit=false;//服务器未启动 publicServerThread(ServerFrameserverFrame){ this.serverFrame=serverFrame; messages=newVector<String>(); clients=newVector<ClientThread>(); users=newHashMap<Integer,String>(); try{ serverSocket=newServerSocket(Port); }catch(IOExceptione){ this.serverFrame.setStartAndStopUnable(); System.exit(0); } broadcast=newBroadCast(this); broadcast.setFlag_exit(true); broadcast.start();//启动广播线程 } @Override publicvoidrun(){ Socketsocket; while(flag_exit){ try{ if(serverSocket.isClosed()){ flag_exit=false; }else{ try{ socket=serverSocket.accept();//接收客户端请求,无请求则阻塞 }catch(SocketExceptione){ socket=null; flag_exit=false; } if(socket!=null){ ClientThreadclientThread=newClientThread(socket,this); clientThread.setFlag_exit(true); clientThread.start();//启动客户端线程 /* *synchronized:当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码。 *同步代码块线程同步(目的是为了保护多个线程访问一个资源时对资源的破坏) */ synchronized(clients){//客户端线程 clients.addElement(clientThread); } synchronized(messages){ users.put((int)clientThread.getId(),"@login@"); messages.add(clientThread.getId()+"@clientThread"); } } } }catch(IOExceptione){ e.printStackTrace(); } } } //停止服务器 publicvoidstopServer(){ try{ if(this.isAlive()){ serverSocket.close(); setFlag_exit(false); } }catch(Throwablee){} } //设置服务器启动标志 publicvoidsetFlag_exit(booleanb){ flag_exit=b; }}(5)ClientThread.javapublicclassClientThreadextendsThread{ publicSocketclientSocket;//客户端套接字 publicServerThreadserverThread; publicDataInputStreamdis; publicDataOutputStreamdos; //publicStringclient_userID; privatebooleanflag_exit=false;//客户端线程启动标记 publicClientThread(Socketsocket,ServerThreadserverThread){ clientSocket=socket; this.serverThread=serverThread; try{ dis=newDataInputStream(clientSocket.getInputStream()); dos=newDataOutputStream(clientSocket.getOutputStream()); }catch(IOExceptione){ e.printStackTrace(); } } @Override publicvoidrun(){ while(flag_exit){ try{ //从通道读出信息 StringMessage=dis.readUTF(); if(Message.contains("@login")){//有新登录用户 String[]userInfo=Message.split("@login"); intuserID=Integer.parseInt(userInfo[1]); serverThread.users.remove(userID); if(serverThread.users.containsValue(userInfo[0])){//新登录的与原来的有重名 for(inti=0;i<serverThread.clients.size();i++){ intid=(int)serverThread.clients.get(i).getId(); if(serverThread.users.get(id).equals(userInfo[0])){//用户名相同 serverThread.users.remove(id); serverThread.users.put(id,userInfo[0]+"_"+id);//额外添加标记(线程ID),更新新登录的用户 break; } } serverThread.users.put(Integer.parseInt(userInfo[1]),userInfo[0]+"_"+userInfo[1]);//更新原来用户 }else{ serverThread.users.put(userID,userInfo[0]); } //更新服务器端用户列表 Message=null; StringBuffersb=newStringBuffer(); synchronized(serverThread.clients){//同步代码块:客户线程 for(inti=0;i<serverThread.clients.size();i++){ intthreadID=(int)serverThread.clients.elementAt(i).getId();//客户线程ID sb.append((String)serverThread.users.get(newInteger(threadID))+"@userlist");//用户姓名+“@userlist” sb.append(threadID+"@userlist");//用户姓名+“@userlist”+客户端线程ID+“@userlist” } } StringuserNames=newString(sb); serverThread.serverFrame.setDisUsers(userNames);//更新用户列表 Message=userNames; }else{ if(Message.contains("@exit")){//有退出,更新用户列表 String[]userInfo=Message.split("@exit"); intuserID=Integer.parseInt(userInfo[1]); serverThread.users.remove(userID);//客户端退出,清除用户ID Message=null; StringBuffersb=newStringBuffer(); synchronized(serverThread.clients){ for(inti=0;i<serverThread.clients.size();i++){ intthreadID=(int)serverThread.clients.elementAt(i).getId(); if(userID==threadID){//移除退出客户端线程 serverThread.clients.removeElementAt(i); i--; }else{//保留未退出客户端信息 sb.append((String)serverThread.users.get(newInteger(threadID))+"@userlist"); sb.append(threadID+"@userlist"); } } } StringuserNames=newString(sb); if(userNames.equals("")){ serverThread.serverFrame.setDisUsers("@userlist"); }else{ serverThread.serverFrame.setDisUsers(userNames); } Message=userNames; }else{ //群聊展示聊天信息 if(Message.contains("@chat")){ String[]chat=Message.split("@chat"); StringBuffersb=newStringBuffer(); SimpleDateFormatform=newSimpleDateFormat("yyyy-MM-ddHH:mm:ss"); Stringdate=form.format(newDate()); sb.append(chat[0]+""+date+"\n"); sb.append(chat[2]+"@chat"); Stringstr=newString(sb); Message=str; serverThread.serverFrame.setDisMess(Message); }else{ if(Message.contains("@single")){ } } } } synchronized(serverThread.messages){ if(Message!=null){ serverThread.messages.addElement(Message); } } if(Message.contains("@exit")){ this.clientSocket.close(); flag_exit=false; } }catch(IOExceptione){} } } //关闭客户端线程 publicvoidcloseClienthread(ClientThreadclientThread){ if(clientThread.clientSocket!=null){ try{ clientThread.clientSocket.close(); }catch(IOExceptione){ System.out.println("server'sclientSocketisnull"); } } try{ setFlag_exit(false); }catch(Throwablee){ e.printStackTrace(); } } publicvoidsetFlag_exit(booleanb){ flag_exit=b; }}(6)BroadCast.javapublicclassBroadCastextendsThread{ ClientThreadclientThread; ServerThreadserverThread; Stringstr; privatebooleanflag_exit=false;//广播线程未启动 publicBroadCast(ServerThreadserverThread){ this.serverThread=serverThread; } @Override publicvoidrun(){ booleanflag=true;//有人在线标记 while(flag_exit){ synchronized(serverThread.messages){ if(serverThread.messages.isEmpty()){ continue; }else{ str=(String)serverThread.messages.firstElement(); serverThread.messages.removeElement(str); if(str.contains("@clientThread")){ flag=false; } } } synchronized(serverThread.clients){ for(inti=0;i<serverThread.clients.size();i++){clientThread=serverThread.clients.elementAt(i);if(flag){ try
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 社交网络平台运营与维护服务合同
- 小产权交房合同模板
- app经销商合同模板
- 社交平台使用协议
- 影院投放娃娃机合同模板
- 不良木材收购合同模板
- 2024年工程保修新规定:维护双方权益
- 家装维修合同模板
- 家政劳务派遣合同模板
- 关于场地出租合同模板
- 安徽壹石通化学科技有限公司年产5万吨氢氧化镁、5万吨碱式碳酸镁、1万吨氧化锆、1000吨硼酸锌、1000吨五硼酸铵和100吨钛酸钡产品项目环境影响报告书
- VASP自旋轨道耦合计算错误汇总
- 唐朝服饰专题知识
- (完整)劳动关系转移三方协议
- GB/T 16907-1997离心泵技术条件(I类)
- GB 4789.15-2016食品安全国家标准食品微生物学检验霉菌和酵母计数
- 突发公共卫生事件报告与应急处置
- GA 98-2005混凝土结构防火涂料
- 三级安全教育试题(水稳班组)
- 商场竞争策略概述
- 做情绪的主人-公开课课件
评论
0/150
提交评论