网络编程课程设计+端口扫描+java实现+源码吴学之_第1页
网络编程课程设计+端口扫描+java实现+源码吴学之_第2页
网络编程课程设计+端口扫描+java实现+源码吴学之_第3页
网络编程课程设计+端口扫描+java实现+源码吴学之_第4页
网络编程课程设计+端口扫描+java实现+源码吴学之_第5页
已阅读5页,还剩14页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

.PAGE.课程设计任务书题目网络端口扫描软件的开发学院<部>信息工程学院专业网络工程班级网络学生姓名吴学之学号201124076月30日至7月4日共1周指导教师<签字>系主任<签字>2014年6月30日目录TOC\o"1-2"\h\u14521设计任务与要求3276202系统功能描述377942.1功能概述366842.2本系统要实现的功能3256803系统总体设计3103773.1总体分析392343.2界面设置构思图417433.3界面使用设置构思453133.4后台设计构思5260814系统详细设计6269584.1界面设计69094.2界面设计图6277534.3后台设计6234165实现与测试10245925.1运行要求与环境10125245.2运行程序流程图11262715.3运行界面12164206设计总结1810603参考文献196912附件201设计任务与要求加深对《Java面向对象程序设计》课程所学知识的理解,进一步巩固Java语言的语法规则。分析系统的可行性,让系统有一个明确的方向,使开发更具合理性,并能分析出系统的具体流程,为后面的开发做好铺垫。明确本次课程设计所要用到的技术点并到网上搜索以及查阅相关的书籍来搜集资料。通过编写一个基于Java的应用系统综合实例,来掌握Java语言编程技巧。并学会编制结构清晰、风格良好的Java语言程序,从而具备解决综合性实际问题的能力,学会使用Java编程工具,如EditPlus,Eclipse等。2系统功能描述2.1功能概述多线程端口扫描器是实现计算机的端口的扫描,只要在在前台设置好所要扫描的IP、起始端口、结束端口以及所要用到的线程数,点击扫描,就可以扫描到所输入IP地址主机的开放端口,并显示在主窗体中;点击退出,则可以退出该程序。IP设置应为所在主机的IP地址,起始端口和结束端口应为0~65535之间的一个数,且起始端口应小于结束端口的大小。线程数为0~200之间的一个数。点击开始后就会运行,直到扫描完毕显示出开放端口,如果没有开放端口,则只显示扫描完毕。2.2本系统要实现的功能①端口扫描功能:扫描开放的端口,并将扫描到的开放端口号送到前台。②图像显示功能:显示界面图形。③多线程功能:当客户端要求与服务器端建立连接时,服务器端就将用到多线程功能,为每一个建立起来的连接创建一个线程。④异常抛出功能:对于明显的错误,能提示出错误的类型并结束程序的运行。3系统总体设计3.1总体分析本程序分为前后台系统,后台系统用于扫描主机开放端口,并把节扫描的数据送至前台窗口显示;前台要显示扫描的结果,所以应为一个窗口,这个窗口应能够设置主机的IP地址,设置端口的开始端口、结束端口和线程数,并且还能够显示扫描的状态。在中央是显示结果的窗体。本程序还应能够有控制扫描的状态命令,附加设置最小化和关闭按钮。3.2界面设置构思图3.3界面使用设置构思当出现如图所示的界面时,填写好要扫描的IP地址,需要扫描的端口范围和线程数,单击命令提示按钮就可以开始扫描,扫描结果就会显示在中间的扫描结果显示区域,在扫描状态显示区就会显示是否扫描完毕。流程图如下:界面出现界面出现填写IP地址或者用默认的IP设置扫描需要的线程数或者是用默认的线程数单击命令按钮开始扫描扫描结束,显示结果显示在结果显示区域是否继续退出结束否是图2系统构思流程图3.4后台设计构思后台系统使用Scanner和Scan类,创建前台布局和创建扫描端口、事件处理,并且能对简单的错误进行判断,显示错误原因。调用数据处理包,处理异常情况;调用皮肤包,美化显示窗口。4系统详细设计4.1界面设计本程序界面图形设计要能清楚显示扫描后的结果,并且能很好的体现出界面的整洁大方,但并不失去吸引人眼球的画面,所以在做界面的时候考虑了界面的色彩,并且添加了皮肤,界面上面的字体设置和windows窗口设置一样采用宋体,界面上的按钮不设置过多的按钮,仅设置有必要的按钮即可,界面设置大方。使用的时候有默认的IP地址、需要扫描的端口和线程数,如果需要扫描其他主机,只需要填写好要扫描的主机的IP地址,需要扫描的端口范围和线程数,单击命令提示按钮就可以开始扫描,扫描结果就会显示在中间的扫描结果显示区域,在扫描状态显示区就会显示是否扫描完毕。4.2界面设计图本程序采用小窗口形式,外围大小为170mm*90mm,字体采用宋体五号,结果显示区域框架大小为160mm*45mm,结果显示字幕为主机地址加开放端口。添加个性皮肤。其余地方设置按钮和扫描的主机地址、端口和线程数。设计的预计页面图形如图:显示红色添加个性皮肤显示红色添加个性皮肤4.3后台设计本程序使用了为主要的Scanner类和Scan类。Scan类的作用是创建线程扫描端口,然后把结果显示到前台。Scanner类的作用是构造前台布局,调用Scan类添加事件处理,对输入进行错误判断,如果输入不在允许的范围之内则显示相关错误。在本程序中用到了网络编程的两个类,下面介绍这两个类的常用方法。InetSocketAddress类构造方法如下:InetSocketAddress<InetAddressaddr,intport>:根据IP地址和端口号创建套接字地址。InetSocketAddress<intport>:创建套接字地址,其中IP地址为通配符地址,端口号为指定值。InetSocketAddress<Stringhostname,intport>:根据主机名和端口号创建套接字地址。Socket类常用方法如下:Socket<>:通过系统默认类型的SocketImpl创建未连接套接字Socket<InetAddressaddress,intport>:创建一个流套接字并将其连接到指定IP地址的指定端口号。voidbind<SocketAddressbindpoint>:将套接字绑定到本地地址。voidclose<>:关闭此套接字。voidconnect<SocketAddressendpoint>:将此套接字连接到服务器。voidconnect<SocketAddressendpoint,inttimeout>:将此套接字连接到具有指定超时值的服务器。booleanisClosed<>:返回套接字的关闭状态。booleanisConnected<>:返回套接字的连接状态。本程序还调用其他的一些类和包,比如软件包java.awt.color、、io.IOException、Javax.Swing、jvnet.substance.*。包的的描述:提供用于颜色空间的类。它包含了基于国际色彩联盟<ICC>配置文件格式规范的颜色空间实现。它还包含了基于ICC配置文件格式规范的颜色配置文件。用来使界面更加具有色彩。Result.setBackground<Color.PINK>;//设置窗口为粉红java.awt.event的描述:提供处理由AWT组件所激发的各类事件的接口和类。事件由事件源所激发,向事件源注册的事件侦听器可接收有关特定事件类型的通知。此包定义了事件和事件侦听器,以及事件侦听器适配器,它是让事件侦听器的编写过程更为轻松的便捷类。在本程序中使用:publicvoidactionPerformed<ActionEvente>{ Stringcmd=e.getActionCommand<>; if<cmd.equals<"Start">>…………}io.IOException包的描述:用来处理io的错误,不仅仅是文件读写,还包括很多stream的读写,而且throws是用来放在函数定义的函数体前函数名后的,表示这个函数将会在出现异常的书后会抛出io异常,所以在以后的程序中调用这个函数的时候就必须用try和catch来捕获异常,否则编译会报错,这主要涉及到java的安全机制。本程序中使用如下:try{ minPort=Integer.parseInt<PortStart.getText<>>; maxPort=Integer.parseInt<PortEnd.getText<>>; threadNum=Integer.parseInt<ThreadNum.getText<>>; }catch<NumberFormatExceptione1>{ DLGError.setBounds<300,280,299,120>; DLGINFO.setText<"错误的端口号或线程数!端口号和线程数必须为整数!">; DLGINFO.setBounds<10,20,280,20>; OK.setBounds<110,50,60,30>;DLGError.setVisible<true>; return;…………}Javax.Swing集合描述:由所有Java图形用户界面〔GUI组件所构成,可运行在任一支持Java虚拟机〔JVM的本地平台上。由于这些组件全都是用Java语言编写的,因此它们可以提供比本地平台GUI组件更多的功能。〔与抽象窗口工具箱对比。JavaSwing是JavaFoundationClasses〔JFC的一部分。在Swing中,Sun开发了一个经过仔细设计的、灵活而强大的GUI工具包。Swing是在AWT组件基础上构建的。它所提供的功能要比AWT提供的更为广泛。它也是Java技术的一种标准配置。Swing模型一个JavaGUI通常由顶层容器、中间容器以及多个原子组件组成。每个原子组件或容器都可能触发相应事件的产生。容器是一类能够在其中容纳其他组件的特殊组件。Swing的GUI组件类是按照类属层次以树状结构进行组织的。在这个树的最顶层,即树的根部,使一个最基本的容器类,被称为顶层容器。Swing提供了三个通用的顶层容器类JFrame,JDialog和JApplet。JFrame提供了基于窗体的应用程序,JDialog提供对话框形式的界面,JApplet提供Java小应用程序的界面形式。在顶层容器下是中间容器,用于容纳其他的组件。通常窗格本身在显示界面中是看不到的。面板类Panel是一种中间容器,它的唯一作用是使组件更容易定位。顶层容器通过getContentPane<>方法获取内部的一个内容窗格。Swing包的组成:javax.swing:基本Swing包,包括Swing容器、组件及相关设置的类和接口。javax.swing.border:包括与边界设计相关的类和接口。javax.swing.colorchooser:与颜色选择相关的类和接口。javax.swing.event:包括事件处理相关的类和接口。javax.swing.filechooser:包括对文件进行查看选取的相关类。javax.swing.plaf:包括一些对外观样式操作的类和接口。javax.swing.tree:包括对树形组件进行操作的类和接口。常用Swing组件:按钮:utton文本区:JTextArea文本字段:JTextField在本程序中使用如下://设置主窗体位置和大小 mainFrame.setBounds<180,200,550,300>; mainFrame.addWindowListener<newWindowAdapter<>{ publicvoidwindowClosing<WindowEvente>{ System.exit<0>;//设置扫描按钮和退出按钮 Start.setBounds<405,232,60,30>; Start.setActionCommand<"Start">; Start.addActionListener<this>; Exit.setBounds<475,232,60,30>; Exit.setActionCommand<"Exit">; Exit.addActionListener<this>;jvnet.substance.*:目的是提供一个流行的外观〔look&feel。//设置窗体皮肤SubstanceAutumnLookAndFeel.setSkin<newFieldOfWheatSkin<>>;5实现与测试5.1运行要求与环境〔1性能要求实时性好、可靠性强、不占用系统太多的内存和存储空间。〔2设计约束开发工具:Eclipse运行环境:Windows2000以上能实现用户所定义的各项需求。5.2运行程序流程图在Eclipse中右击,选择运行方式,JAVA应用程序在Eclipse中右击,选择运行方式,JAVA应用程序填写IP地址,可填写任意的一个IP出现程序界面设置开始端口大小,设置0~65535之间的端口号且必须为整数设置结束口,设置0~65535之间的端口号且必须为整数,并且大于开始端口设置进程数,0~200之间且必须为整数点击扫描可以开始扫描结果显示是否继续扫描结束程序否,点击退出是,重新设置图4流程图5.3运行界面图5运行界面图未扫描状态图6运行界面未扫描状态图正常扫描后状态图7运行界面正常扫描状态图起始端口设置有误扫描开始后状态报错扫描结果保存线程数设置错误报错端口扫描完成6设计总结在此次课程设计中,遇到了一些问题,如:程序功能不能完全实现,对于面向对象的方法了解不够透彻,运用到实际的软件开发中存在着困难;对于Java语言,以前只学习到了一些最基本的知识,要在短时间内用Java语言来开发软件是一个较大的挑战;对于开发软件的流程不熟悉,适应起来比较慢,编写需求说明书和设计规格说明书时,自己感觉难以动手,这表明所学的知识不能灵活运用到实际中。对于以上的问题,自己有清楚的认识,解决办法是需要大量阅读相关的书籍,多看些项目的源代码。对于书上以及网站上下载的资料中的Java实例必须理解,还有多跟精通JAVA语言的老师和同学请教和交流,取其精华。对于实际动手能力与软件开发的流程的适应,必须多进行实际的练习与操作,才能有所进步。我自己感觉此次课程设计做得挺成功的,通过这一次实践编程,我学到了不少有关JAVA的实际编程的知识。在这次设计开始的第一天开始,我就开始着手修改一个用JAVA编写的短线呈端口扫描的程序。我刚开始很自信自己能修改成功,但这一过程太不顺利。用了两天时间来修改那个JAVA程序,但调试的时候都没有成功。后来我请教一个班上成绩好的同学,在他的帮助下我不断的发现错误,并改正它们,功夫不负有心人人,我的程序最后运行成功了。在这课程设计期间我的同学和老师帮助了我,有些东西是我们一起探讨,一起解决方法的。当然在学习Java和设计程序的过程中还得到了杭志老师的辛勤指导,为我解答了不少的疑问。同时,在老师身上我们学到了很多实用的东西,在此表示衷心的感谢!同时,还要感谢帮助过我的其他同学!这次课程设计令我感受很多。从拿到题目到改编JAVA程序;然后请教别人慢慢研究琢磨;从理论到实践;从失败到成功;忘不了我坐在电脑前苦苦思索,高温下熬夜地编程的疲惫;忘不了因沉迷于编程却耽误了吃饭时间而挨饿辛酸;忘不了……这其中了不少的东西,磨砺了我的意志;同时还巩固了以前所学的知识,学到了不少书本上没有的知识;学到了很多java编程知识,并学会了简单的使用eclipse来开发java程序的一些使用技巧这次课程设计是对我本学期所学的知识的检验,由此我发现了不少的问题。可以说它给了我一次自我评估的机会。通过设计让我知道了那些方面我还是有欠缺的,促使我花时间弥补。临近考试,时间太紧迫,致使程序实现的功能在方法上也许不是很完美,但我以后会多向老师请教,自己也要加强对Java的学习。努力进一步提高自己的编程水平。此次的课程设计,对我来说撰写文档似乎是一个更大的挑战。撰写文档不仅要求我们要对自己程序非常熟悉:程序的总体框架,功能,如何实现,存在什么问题等,同时还要求我们有清晰的思维和准确的表达能力以及严密的逻辑性。因此,写完这篇文档对于我们自身来说自然是获益匪浅的。参考文献[1]SharonZakhourScottHommel等著.Java语言导学.人民邮电出版社,2008[2]耿祥义编著.Java基础教程.清华大学出版社,2004[3]JoeWigglesworthPaulaLumby.Java程序设计高级主题.北京大学出版社,2004[4]Y.DanielLiang著,王镁等译.Java语言程序设计基础篇.2006[5]朱福喜等.Java项目设计与开发范例.电子工业出版社,2005附件/*基于多线程端口扫描程序源代码*/packagescanner;/*基于多线程端口扫描程序源代码*/importjava.awt.BorderLayout;importjava.awt.Color;//类的调用importjava.awt.Container;importjava.awt.Dimension;importjava.awt.Frame;importjava.awt.Graphics;importjava.awt.Image;importjava.awt.Label;importjava.awt.TextArea;importjava.awt.Toolkit;importjava.awt.event.ActionEvent;importjava.awt.event.ActionListener;importjava.awt.event.WindowAdapter;nt;importjava.io.BufferedReader;importjava.io.BufferedWriter;importjava.io.DataInputStream;importjava.io.DataOutputStream;importjava.io.FileNotFoundException;importjava.io.FileReader;importjava.io.FileWriter;importjava.io.IOException;importjava.io.InputStream;importjavax.swing.ImageIcon;importjavax.swing.utton;importjavax.swing.JDialog;importjavax.swing.JFileChooser;importjavax.swing.JFrame;importjavax.swing.JLabel;importjavax.swing.JTextField;publicclassScannerextendsJFrameimplementsActionListener{ publicstaticvoidmain<String[]args>{ newScanner<>;// newFrame1<>;// Frame.repaint<>; } //创建主窗口 staticintj=0; //Imageimg=Toolkit.getDefaultToolkit<>.getImage<"images/123.jpg">;JLabelphoto1=newJLabel<newImageIcon<"images11/2.gif">>;JLabelphoto2=newJLabel<newImageIcon<"images11/1.gif">>; publicstaticJFrameFrame=newJFrame<>; publicstaticLabellabelIP=newLabel<"主机IP">; publicstaticLabellabelPortStart=newLabel<"起始端口:">; publicstaticLabellabelPortEnd=newLabel<"结束端口:">; publicstaticLabellabelThread=newLabel<"线程数:">; publicstaticLabellabelResult1=newLabel<"扫描结果:">; publicstaticLabelState=newLabel<"扫描状态:">; publicstaticLabelScanning=newLabel<"扫描待命">; publicstaticLabelTimeout=newLabel<"请求超时:">; publicstaticJTextFieldhostName=newJTextField<"">; publicstaticJTextFieldPortStart=newJTextField<"130">; publicstaticJTextFieldPortEnd=newJTextField<"140">; publicstaticJTextFieldThreadNum=newJTextField<"5">; publicstaticJTextFieldtime=newJTextField<"2000">; //文本区域,显示扫描结果 publicstaticTextAreaResult1=newTextArea<>; publicstaticTextAreaResult2=newTextArea<>; publicstaticLabelDLGINFO=newLabel<"">; publicstaticuttonStart=newutton<"开始扫描">; publicstaticuttonExit=newutton<"扫描退出">; publicstaticuttonsave=newutton<"保存">; //错误提示对话框 publicstaticJDialogDLGError=newJDialog<Frame,"ERROR">; publicstaticuttonOK=newutton<"OK">; publicScanner<>{ //设置窗体皮肤 //SubstanceAutumnLookAndFeel.setSkin<newFieldOfWheatSkin<>>; //设置主窗体名称 Frame.setTitle<"网络编程课程设计:网络端口扫描软件的开发">; //设置主窗体位置和大小 //Frame.setSize<560,510>; Frame.setSize<560,510>; Frame.addWindowListener<newWindowAdapter<>{ publicvoidwindowClosing<WindowEvente>{ System.exit<0>; } }>; //设置扫描按钮和退出按钮 Start.setBounds<160,232,90,30>; Start.setActionCommand<"Start">; Start.addActionListener<this>; Exit.setBounds<455,445,90,30>; Exit.setActionCommand<"Exit">; Exit.addActionListener<this>; save.setBounds<5,445,90,30>; save.setActionCommand<"save">; save.addActionListener<this>; labelIP.setBounds<17,13,50,20>; Timeout.setBounds<290,45,55,20>; hostName.setBounds<67,10,92,25>; hostName.setHorizontalAlignment<JTextField.CENTER>; labelPortStart.setBounds<162,13,60,20>; PortStart.setBounds<227,10,45,25>; PortStart.setHorizontalAlignment<JTextField.CENTER>; labelPortEnd.setBounds<292,13,60,20>; PortEnd.setBounds<357,10,45,25>; PortEnd.setHorizontalAlignment<JTextField.CENTER>; labelThread.setBounds<422,13,50,20>; ThreadNum.setBounds<477,10,45,25>; time.setBounds<350,44,55,20>; ThreadNum.setHorizontalAlignment<JTextField.CENTER>; labelResult1.setBounds<1,232,60,30>; Result1.setBounds<1,65,270,160>; //photo.setBounds<230,75,320,220>; photo1.setBounds<230,65,350,220>; photo2.setBounds<500,510,550,220>; Result1.setEditable<false>; Result1.setBackground<Color.RED>; Result2.setBounds<1,280,542,160>; Result2.setEditable<false>; Result2.setBackground<Color.GREEN>; State.setBounds<1,45,55,20>; Scanning.setBounds<60,40,120,30>; //设置错误提示框 ContainerdisplayPanel=DLGError.getContentPane<>; displayPanel.setLayout<null>; displayPanel.add<DLGINFO>; displayPanel.add<OK>; OK.setActionCommand<"OK">; OK.addActionListener<this>; //在主窗体中添加其他组件 Frame.setLayout<null>; Frame.setResizable<false>; Frame.add<Start>; Frame.add<Timeout>; Frame.add<time>; Frame.add<Exit>; Frame.add<save>; Frame.add<labelIP>; Frame.add<hostName>; Frame.add<labelPortStart>; Frame.add<labelPortEnd>; Frame.add<PortStart>; Frame.add<PortEnd>; Frame.add<labelThread>; Frame.add<ThreadNum>; Frame.add<labelResult1>; Frame.add<Result1>; Frame.add<Result2>; Frame.add<State>; Frame.add<Scanning>; Frame.add<photo1>; Frame.add<photo2>; Frame.setResizable<false>; Frame.setVisible<true>; } //错误产生的几个原因 publicvoidactionPerformed<ActionEvente>{ Stringcmd=e.getActionCommand<>; if<cmd.equals<"save">>{// Stringstr=Result2.getText<>; try{ BufferedWriterbw=newBufferedWriter<newFileWriter<"C:\\Users\\loveinparadise\\Desktop\\"+"扫描结果"+j+".txt">>; bw.write<Scan.str>; Scan.str="";// bw.write<"\r\n">; bw.newLine<>; bw.close<>; }catch<IOExceptione1>{ //TODOAuto-generatedcatchblock e1.printStackTrace<>; } } if<cmd.equals<"Start">>{ Result1.setText<null>; Result2.setText<null>; j++; try{ Scan.hostAddress=InetAddress.getByName<Scanner.hostName .getText<>>; Scan.time=Integer.parseInt<Scanner.time .getText<>>; } catch<UnknownHostExceptione1>{ DLGError.setBounds<300,280,160,110>; DLGINFO.setText<"主人,这是错误的IP地址or域名">; DLGINFO.setBounds<25,15,100,20>; OK.setBounds<45,40,60,30>; DLGError.setVisible<true>; return; } intminPort; intmaxPort; intthreadNum; try{ //获取输入数据 minPort=Integer.parseInt<PortStart.getText<>>; maxPort=Integer.parseInt<PortEnd.getText<>>; threadNum=Integer.parseInt<ThreadNum.getText<>>; }catch<NumberFormatExceptione1>{ DLGError.setBounds<300,280,299,120>; DLGINFO.setText<"主人,错误的端口号或线程数,端口号和线程数须为整数!">; DLGINFO.setBounds<10,20,280,20>; OK.setBounds<110,50,60,30>; DLGError.setVisible<true>; return; } //输入信息错误处理 if<<minPort<0>||<maxPort>65535>||<minPort>maxPort>>{ DLGError.setBounds<300,280,295,120>; DLGINFO.setText<"最小端口必须是0-65535并且小于最大端口的整数">; DLGINFO.setBounds<10,20,280,20>; OK.setBounds<120,50,60,30>; DLGError.setVisible<true>; return; } if<<threadNum>200>||<threadNum<0>>{ DLGError.setBounds<300,280,184,120>; DLGINFO.setText<"进程数必须是1-200中的整数">; DLGINFO.setBounds<10,20,200,20>; OK.setBounds<55,50,60,30>; DLGError.setVisible<true>; return; } Result1.append<"正在扫描"+hostName.getText<>+"线程数:"+threadNum +"\n">; Scanning.setText<"开始扫描">; Result1.append<"开始端口"+minPort+"结束端口"+maxPort+"\n">; //多线程算法核心代码 for<inti=minPort;i<=maxPort;>{ if<<i+threadNum><=maxPort>{ newScan<i,i+threadNum>.run<>;//类Scan引用run<>方法 i+=threadNum; }else{ newScan<i,maxPort>.run<>;

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论