Windows平台下TCPIP协议的设计与实现_第1页
Windows平台下TCPIP协议的设计与实现_第2页
Windows平台下TCPIP协议的设计与实现_第3页
Windows平台下TCPIP协议的设计与实现_第4页
Windows平台下TCPIP协议的设计与实现_第5页
已阅读5页,还剩16页未读, 继续免费阅读

下载本文档

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

文档简介

1、优秀目录1. 引言12. tcp/ip协议概述13. tcp/ip协议的系统设计24. tcp/ip协议的系统实现35. 结论116. 详细设计代码13wi ndows平台下tcp/1p协议的设计与实现1. 引言本文背景基丁一个tcp/ip协议改进项目,项目耍求通过改进tcp/ip协议拥塞控制 算法 來提高无线网络环境卜的数据乔吐量。目前的tcp协议在无线网络环境下无法 区分岀拥塞丢包与误码丢包,根据这两种不同的丢包原因需要对tcp的窗口进行不 同的调整,因此需 要对现有的tcp/ip协议进行改进。针对这个需求提供的一个解 决方案就是口己开发出一套tcp/ip协议以替代系统tcp/ip协议,但

2、是并不需要实现 整个tcp/ip议族,重点实现tcp与ip协议即可。2. tcp/ip协议驱tcp/ip协议是internet的技术基础。internet是一个丿'-域网,是目前联通世界上 绝大多数国家和地区的全球性信息系统。在internet上,可以实现低成本、高速率、 交互式的信息 杳询、信息发布、通讯联络以及协同作业等等现代化的工作、学习 和生活。tcp/ip协议族通常分为四个层次,应用层、传输层、网络层和链路层。如图1所示:应用层(ftp, smtp等)传输层(tcp, udp等)网络层仃p, icmp等)链路层(网卡驱动等)图1 tcp/ip协议族四层结构应用层向用户提供一组

3、常用的应用程序,比如电了邮件(smtp)、文件传输访问(ftp)、远程登录(telnet)等。传输层提供进程间端到端的通信。在tcp/ip协议族屮,主要有两种不同的传输 协议:传输控制协议(tcp)和用户数据报协议(udp) o tcp提供面向連接的、可靠的(没 冇数据重复或丢失),全双工的数据流传输服务。而udp则捉供的是不可靠的而向 无连接的数据传输服务,其可靠性应由上层应用程序來支持。网络层,主要负责数据包的分组及路由选择。在tcp/tp协议族中,网络层协议包括 网际协议ip、互连网控制报文协议icmp、地址转换协议arp和反向地址转换协议rarr。链路层处于四层结构的最低层,负责接收i

4、p数据报并通过网络发送之,或从网 络上接 收物理帧,抽出ip数据报,交给ip层。通常包括网络设备驱动程序及网络 接口卡等。3. tcp/ip协议的系统设计以windows网络体系结构为基础,参照windows ddk屮关于网络协议驱动与传输驱动 接口(tdi)的相关资料,以及考虑到与原有系统tcp/ip兼容,提出的设计方案如图2 所示。win 32 apitdi客八td1扌攵i indis扌如itd1役输器下层微錮n駅动(miniport driver)图2 tcp/ip协议设计框图应用程序也就是根据协议开发的特定应用。这里是针对开发的tcp/ip协议编写 的一个ftp小应用程序,用来测试开发

5、的协议。应用程序通过win32 api接口将其操作转化成相应的请求提交给tdi客户。传输驱动程序接口(tdt)客户是核心态的驱动程序。它的主要功能是完成上层 应用 程序的请求,或者根据该请求产生相应的tdi操作,并将该操作传递给下层的 tdi传输器。tdi客户通过win32 api接口与上层应用程序交互;通过tdi接口与下层 td1传输器进行交互。tdi传输提供者(tdi transport provider)又称为tdi传输器,dis协议驱动程 序,以及协议驱动程序,是工作在核心态的协议驱动程序。其中tcp协议,叩协议, arp协议 等都是在这个模块屮实现。它通过tdi接口与上层的tdi客户

6、进行交互;通 过ndis接口与下层微端口駆动进行交互。nd1s下层微端口驱动程序是工作在核心态的驱动程序,它负责将td1传输器接入 至特 定的网络适配器。它通过ndis接口与上下层进行交互。4. tcp/ip协议的系统实现由图2中可以看岀,整个系统可分为四部分,应用程序、tdi客户、td1传输器和 卜层 微端口驱动。事实上对于下层微端口驱动并不需要考虑,因为可以直接调用 ndts库函数将数据转发到这层,处于这层上的驱动会自动将数据送出网络适配器。 因此真正需要开发的也 就是上面三个部分。应用程序是用来实现简単文件传输的, 因此考虑开发两个小应用程序,一个为服务器端,一个为客户端,服务器端用来

7、监听和处理来自客户端的连接请求。客户端主要是向服务器端请求连接和发送数 据。tdi客户负责将来口应用程序的请求进行相应的处理z后转发给卜层的tdi传输 驱动。tdt传输驱动主要是实现tcp, tp等功能,并与下层的ndis接口进行交互。 4.1应用程序的实现客户端可以通过本地的某个端口向对方发送数据。并显示一些错谋状态。 服务器端,可以指定在本地的某个端口监听连接请求,接收数据,并显示一些状态。 实现:通过devicelocontrol及相应controlcode来将命令传输到下层的tdi客 户。主要接口 函数:createfile 和devicelocontrolcreatefile函数原型

8、:handle createfile(lpctstr ipfilename,dword dwdesi red a ccess,dword dwsharemode,lpsecurity_attributes ipsecurityattributes,dword chvcreationdisposition,dword dwflagsandattrihutes,handle htemplatefile);ipfilename在这里就是指向要操作的tdi客户(驱动)的符号链接,符号链接是 下层驱动程序对win32子系统可见的引用符号,也就是代表了一个下层的张动。这个函 数的功能是打开下层的tdi客户

9、,并返回该设备句柄,以后对设备的所有操作都是通过该 句柄來引用。devicelocontrol 函数原型:bool deviceiocontrol(handle hdevice.dword dwiocontrolcode,lpvoid ipinbuffer,d word nlnbuffersize,lpvoid ipoutbujfer,dword noutbuffersize,lpd word ip bytes re tu rn ed,lp over la pped ipoverlapped);hdevice和dwiocontrolcode是这里最重要的两个参数。前者是前而createfile

10、返 回的句柄,代表设备对象,在这里即是下层的tdi客户,表明是对它进行操作;后者是i/o 控制码,表明要在该设备上进行的操作类型,如发送数据,这个控制码可以是口定义的。 在应用程序调用了devicciocontrol z后就将操作请求提交给了处于系统内核中 的tdi客户。4.2 tdi客户的实现tdi客户将上层应用程序发过来的i/o请求包(irp)进行处理,能在木层处理的则 处理后直接返回,需要底层继续完成的则先将当前的irp状态设置为挂起,然后重新设 置一个trp移交给下层驱动继续处理。实现:主要是tirdctcpiocontroldispatch派遣例程的实现。这个派遣例程与devicel

11、ocontrol函数相对应。其主要功能是根据应用程序的不同请求(携带在irp 屮的iocontrolcode)进行不同的处理。只是这里需耍额外考虑的是,需要在tdi客户的 该例程屮事先判断下是对服务器端的tdi客户操作还是针对客户端的tdi客户进行操 作。主要接口函数:xxxjocontroldispatch,tdibuildxxx 和iocalldriveroxxxjocontroldispatch 函数原型:ntstatusxxx_devi celo controlin pdevice_objectpdeviceobject,in pirp plrp);驱动程序屮注册的派遣例程都是pdev

12、iceobject和plrp这两个参数,前面代表了要 操作的设备对彖,后者代表i/o请求类型。pdeviceobject在这里具体的是只指服务器 端的tdi客户或客户端的tdi客户。现在以服务器的tdi客户为例,假设要对其进行一个监 听操作,则此吋irp屮所携带b'jiocontrolcode则是一个代表监听操作的控制码。这个函数 就是根据不同的控制码来决定要进行的操作直接完成irp或者是转发请求到下层。对于我们的协议來说,很多情况下tdi客户是不能独立完成一个irp请求的,需要 转发到下层也就是它的tdi传输器来继续完成irp的。这个吋候就会用到后面的两个 重要函数tdibuildx

13、xx,和iocalldriver 了。tdibuildxxx函数原型:根据10控制码的不同,该函数的声明也稍有区别。仍旧接着前面的事例,tdi客 户不能够独口完成应用程序的监听请求,因此需要借助tdibuildxxx函数来牛成相应 的 irp,交给卜层的tdi传输器进行处理。这里的xxx既代表不同的操作,对于监听来说, 既是tdibuildlisteno其函数原型如下:voidtdibuildlisten(pirp irpfpdevice_object devobj,pfile_object fileobj,pvoid comproutine,pvoid contxt,ulong flags,

14、ptd1_connectionnf0rmat10n requestconnectionlnfo.ptdiconnectionjnformation returnconnectionlnfo);这个函数中最重要的三个参数是irp、devobj和fileobj,第一个是预先分配好的一 个irp结构体指针;第二个是这个irp将要转发到的设备对象,也就是tdt传输器; 第三个是tdi传输器的文件对象指针,可以是代表传输地址的文件对象,可以是代 表连接端点的文件对彖,可以是代表控制信道的文件对彖,不同的文件对象上可以进行的操作也不一 样,比如tdi.listen操作只可以在代表连接端点的文件对象上进行。

15、该函数主要 是对新建的irp进行设置,关键是给这个irp设置了操作码为tdllisten.在创建了这个irp以后, tdi客户将这个irp请求转发到它的tdi传输器,这个过程是通过调用 iocalldriver函数来实现的。localldriver 函数原型:ntstatusiocalldriver(in pdevice_object deviceobjectfin out pirp irp);该函数将irp请求转发给指定的设备对象。在我们的程序中,既是将tdi客户中生 成的irp发给下层的tdi传输器,即我们的协议驱动进行处理。deviceobject为代表f 层 tdi传输器的设备对象,i

16、rp为要进行的操作,如而面事例中生成的tdllisten请求。 在tdi客户调用iocalldriver之后,irp请求就转到了tdi传输器,即我们的tcp/ip协议中处理了。4.3 tdi传输器的实现tdi传输器也就是我们的协议驱动,也就是tcp/ip协议。简单的说,这层的主要 操作仍然是根据上层tdi客户捉交过来的请求进行不同的处理。只不过这里又冇特殊的 含义,就是耍完成tcp/ip的相应功能,因此这一层是我们实现中最重耍的部分。在这层中,tdi传输器接收到上层tdi客户转交过來的请求,系统根据用户注册 的函数入口找到处理请求的函数irdctcpinternaldevicecontrold

17、ispatch。该函数则根据操 作的对彖和操作的类黑进行不同的函数调用。irdctcpinternaldevicecontroldispatch 的函数原型:ntstatusirdctcpinternaldevicecontroldispatch(in pdevice_object deviceobjectfin pirp irp)参数deviceobject代表了当前的设备对象,也就是tdi传输器。irp为irp请求指 针,表明了要操作的文件对象和需要进行的操作。该函数首先根据不同的文件对象 进行分类,然后对某一个文件对象可以进行的操作进行列表。当某一请求到来时, 根据比较这些参数找到对应的

18、操作。以下就按tcp/ip i办议对数据的处理流程详细 进行分析。依数据传输的方向大致可以分成发送和接收过程。4. 3.1发送过程上层应用程序发起一个发送请求。首先应用程序调用createfile函数打开tdi客 户,然后调用devicelocontrol将请求转发到内核的tdi客户,tdi客户进行相应 的处理之后,调用tdibuildsend设置一个tdi.send请求,然后再调用 iocallerdriver将该请求转发给tdi传输器,即tcp/ip协议进行处理。为了描述主 线,这里暂把先前tcp建立连接的三次握手过程给省略了。发送过程如图3所示。图3发送框图数据从tdi客户进入tdi传输

19、器后,经过一系列的函数调用,生成适合在网络上 传输的数据包。这个过程包括对数据的封包,超时,创建重传队列,数据分片,路 由设置等。发送数据时首先双方应该建立连接前完成一个三次握手的过程,在连接 建立以后双方开始进行可靠的通信。图4所示为建立连接以后,发送过程在tcp/ip 协议层屮函数的调用流图。tdi传输器的派逍例程调用tcp_send函数发送数据,将 数据转入到tcp层,完成tcp层的包头以及控制状态的设置。在调用ip_queue_xmit 后,数据转到ip层进行处理,在这里完成ip包格式的设置以及分片操作等。最后 调用ether.output函数设置好mac头以后,一个完整的数据帧就行成

20、了,然而为 了符合ndis对数据包格式的封装要求,这里需要对数拯结构进行调整。数据在进 入ether_output函数前一直是以sk_buff的形式进行管理的,这个结构体冇四个指 针,通过对这四个指针的上下移动來对数据进行操作。在进入ether.output函数z 后数据重新打包成适合ndis接口传输的packet形式。然后调用ndis函数 ndissend函数将数据由下层驱动送出。td1客户图4发送过程tcp/ip协议层函数流程图4. 3. 2接收过程下层网卡接收到数据以后,将通知微端口驱动程序,微端口驱动程序再将数据指示 给ndis协议张动程序进行处理。在协议层中对数据进行一系列的处理之后

21、再通知 给td1客户,tdi客户再将数据通知给上层应用程序。接收过程如图5所示。微靖i 1加动和庁指小的数抑;图5接收框图数据从微端口指示给ndts协议驱动以后,首先将ndis层的数据包格式packet拆 开组装成sk_buff的形式,设置好该结构的各个成员。然后调整它的四个指针来获 取不同层的实际数据。首先分离出mac帧头,判断收到的包是否为ip包,否则直 接丢弃,是则继续往上进入1p层处理。然后分离岀1p头,判断当前包是否分片, 是则等收齐所有分片以后重新组包往上传递,不是则直接上传。最后分离出tcp头, 通过分析tcp头中所携带的信息,以及当前tcp所在的状态來进行相应的处理。如 当前的

22、tcp状态是尚未建立连接则调用tcp_rcv_state_process函数,该函数根据 tcp头中标志位的置位情况来进行相应处理。如果己经建立连接则调用 tcp_rcv_established函数进行数据的接收过程处理,将接收的数据加入队列,当 队列满了以后通过设置事件的信号态來指示上层的tdi客户有数据到达,然后tdi 客户以同样的方式通知上层应用程序。接收过程tcp/tp协议层中的函数调用过程 如下图6所示。tdi紗图6接收过程tcp/tp协议层函数流程图5.结论本文以rfc文档中关于tcp/ip协议的标准规范为理论基础,以windows ddk 为开发工具,结合项目需求,设计开发了一套

23、tcp/tp协议。本套协议并未实现整 个tcp/ip协议族中的所有协议,只是对tcp和ip部分进行了实现。在前面总体协 议框架的设计基础上,最终得到的产品有,ftp测试应用程序,tdi客户及tcp/ip 协议(tdi传输器)。下而是测试该tcp/ip i办议的部分截图。图7为启动加载tcp/ip 协议(irdctcp)与ti)i客户(tditirdctcp)的截图。图8为协议接收数据的截图。file idit channels vie* options help创*©|x|剖ia|a|制ek囲w昌囤tue : message text6b666b6635353597535355355

24、3 7 7 7 7 7 7 7 t ay ay ay ay ay nbqv ay -y qw hmv -y ny ay «y qv qv qw qvirdctcp: drivereittryirdctcp: d:iveren:ry: cancelld 0irdctcp: refopen: open 840bf720, old ref 0, irdctcp: great ebinding: open 840朋720/0, devi( *«x»createbindin:tdire(isterdeviceobject»*> »*>)

25、87;creat ebindin(: tdire(isternetaddress*<* irdctcp: great ebinding: opencomext 840bf72o, irdctcp: pnpevent: open 00000000$ even: 6,st; tdi?irdctcp:tdittcp: driverentn tdi:irdctcp:regis:rypath: registryhachines tdi?irdctcp:tclientjeviceload: entry. tdi?irdctcp:*>*«?client deviceload end*&

26、quot;* tdiirdctcpjtserver.deviceload: entry. tdi?irdctcp:*«?server deviceload end*t* 一 end 一图7启动tcp ip协议与tdi客八截图mwag. tirt irdetcpreceive: entryirdctcp: irdctcpreceivo: receive in ip s4i951e4ooob6&325d90oo0130184l95lf40028bd0840006d06841841952048628if90m1530cb86b84195214fc77b39boo00oo00000i

27、rdctcp: skb.he£roapool: entry. irdctcp: skb.head.froikj>ool: endth* irdctcp: ether recv:entry83fa592000ob6132sd90000130183fa593o0028bd0840006d0684183fa59408628if90041530cb86birdctcp: ip.rcv:entryirdctcp: lp.local.deliver: entry1rdctcp: lp.local.deliver.fmish:entry irdctcp: ip.r«&疝 i

28、rdctcp: lp.lookup.route: look saddr: irdctcp: 1p.add.rout:ent ry. irdctcp: lplookup.route: look saddr:- irdctcp: ip_add.route:end.irdctcp: lplookuproute: look saddr:6图8接收数据截图图7启动tcp/ip i办议与tdi客尸截图图8接收数据截图6.详细设计代码(1)映射网络驱动器功能实现;实现代码如下:u pdatedata(false);dword nretval;netresource nr;nr.dwtype = resour

29、cetype_any;lptstr local =(lptstr)(lpctstr)m_strlocal;nr.lplocalname=t2w(local);lptstr tar =(lptstr)(lpctstr)m_strtar;nr.lprcmotcnamc = t2w(tar);nr.lpprovider = null;nretval = wnetaddconnection2(&nr, m_strpwd, m_struser, false);if(nretval = no.error) cstring strtext;strtext.format(cstringc,映射文件 &

30、#39;%sv 到网络驱动盘 '%s'成功 ”), m_strtar,m strlocal);afxmessagebox(strtext);return;messagebox(cstring("映射网络驱动盘失败!");void cmapdlg:onbnclickedbuttondismap()dword nretval;u pdatedata(true);nretval = wnetcancelconnection2(m_strlocal, connect_update_profile, false);if(nretval = no_error)cstri

31、ng strtext;strtext.format(cstring("断开网络驱动器映射'%s* 成功!h),m_strlocal);messagebox(strtext);return; messagebox(cstring("断开网络驱动器映射失败!");(2) 单个ip共享资源搜索实现。(3) 搜索所冇计算机的共享资源实现。实现代码如下:void ctmpl dlg:onbnclickedok() m_listctrlres.deleteallitems();if(m_operate=0)byte bip4;m_iptar.getaddress(bi

32、po,bip 1 ,bip2,bip );cstring tar add;taradd.format(cstring(” d.%d.%d.%d”),bip0,bipl,bip2,bip3);search(taradd);else if(m_operate= 1)searchall();tchar* ctmpldlg:cstring2tchar(cstring& str) int ilen = str.getlength();tchar* szrs = new tcharlilenj;lstrcpy(szrs, str.getbuffer(ilen);str.releasebuffer(

33、);return szrs;void ctmpl dlg:onbnclickedradioall() getdlgitem(idcpaddress_tar)->enablewindow(0);m_operate= 1;void ctmpldig:onbnclickedradioper() getdlgitem(idcpaddress_tar)->enablewindow(l);m_operate=0;int ctmp 1 dlg:search(cstring tarip) tchar *tmp=cstring2tchar(tarip);pshare_info_1 bufptr,p;

34、net_api_status res;lptstr ipszserver = null;dword er=0,tr=0,resume=0, i;ipszserver = tmp;do / begin do res = netshareenum (ipszserver, 1, (lpbyte *) &bufptr, -1, &er, &tr, &resume); if(res = error.success ii res = error_more_data)p=bufptr;for(i=0;i<er;i+)cstring strnetname =p->

35、shi l_netname;cstring strremark =p->shil_remark;dword dwtype=p->sh订type;cstring strtype;if(dwtype=stype_disktree)strtype=cstring(" w 盘驱动 ”);else if(dwtype=stype_printq)strtype二cstring(”打印机序列”);)else if(dwtype=stype_dev!ce)strtype=cstring(n 通信设备“);else if(dwtype=stype_ipc)strtype=cstring(h

36、 进程间通信(ipc)”);else if(dwtype=stype_special)strtype=cstring(nw 殊共享”);else if(dwtype=stype_temporary)strtype=cstri ng("临时共享”)else strtype.format(cstring("%d"),dwtype); int ncount=m_listctrlres.getitemcount();m_listctrlres.lnsertitem(ncount,tarip,0);m_listctrlres.setitemtext(ncount, 1 ,s

37、trnetname);m_listctrlres.setitemtext(ncount,2,strremark);m_listctrlres.setitemtext(ncount,3,strtype);p+;net api b ufferfree( b ufptr);elseif(res!=error_success&&res! =error_more_d ata&&m_operate=0) messagebox(cstringc's有共享信息!“); while (res=error_more_data); / end doreturn 0;void

38、ctmp 1 dig:searchall(void) lpserver_info_101 pbuf = null;lpserverjnfo_101 ptmpbuf;dword dwlevel = 101;dword dwprefmaxlen = max_preferred_length;dword dwentriesread = 0;dword dwtotalentries = 0;dword dwservertype = sv_type_server;/ all serversdword dwresumehandle = 0;net_api_status nstatus;lptstr psz

39、servername = null;lptstr pszdomainname = null;dword i;wsadata wsadata;wsastartup(makeword(2,0), &wsadata);nstatus = netserverenum(pszservername,dwlevel,(lpbyte *) & pbuf,dwprefmaxlen,& dwentriesread,& dwtotalentries,dwservertype,pszdomainname,& dwresumehandle);讦(nstatus = nerr_su

40、ccess) ii (nstatus = error_more_data) if (ptmpbuf = pbuf) != null) for (i = 0; i < dwentriesread; i+) cstring hostname=ptmpbuf->svl()l_name; char szhostnamel 128= ao*;int hostlength=hostname.getlength(); for(int j=0;j<hostlength;j+)szhostnamej=hostnamej;hostent * ent = gethostbyname(szhostn

41、ame);if(ent=null)ptmpbuf+;continue;cstring strhostip;in_addr* inhostip=(in_addr *)ent->h_addr_listo;strhostip.format(cstring(h%d.%d.%d.%dn),inhostip->s_un.s_un_b.s_blinhostip->s_un.s_un_b.s_b2,inhostip->s_un.s_un_b.s_b3,inhostip->s_un.s_un_b.s_b4);search(strhostip);ptmpbuf+;if (pbuf !

42、= null)netapibufferfree(pbuf);wsacleanupo;(4) 将搜索结果保存为文本实现:将text文档保存在recordo text文档中,上图保存后的文档如下e$注样!pc$汪d$主林f$注科adm1k$鶯鱷ipc$ * ipc$1pc$ t print$ 打印机b类型,打印网络名印机发送至w弟0" 2807聶磊,ipcf 2注释,远献猊"°类型乎等亦幕6晒1111 *1111*

43、11 *6*11331313131317record.txt 记辱本心11i7$5o21m21m殊衣疔疾默編張t络络络络络 网网网网网名名名名名名名名名名冬名名-u u 二九s:二九 ppppppppppppp 机 pp持尊養辛忑 us匕、£、£、t、e、 云 f 4/ 克多 e oht rzfr- s c c c q

44、 opc管iplpip肠cr 聶共共共远共共 达灵认认,认认 戰,默默衮默注:实现代码如下:void ctmpi dlg:onbnclickedbutton2()/ todo:在此添加控件通知处理程序代码int ncount=m_listctrlres.getitemcount();cstring strlpadd;cstring strnetname;cstring strremark;cstring strtype;cfile file;file.open(cstring("record.txt"),cfile:modecreatelcfile:modewrite);for(int i=0;i&l

温馨提示

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

评论

0/150

提交评论