精华内容
下载资源
问答
  • 客户端-服务器-消息-应用程序 Java 客户端服务器消息应用程序。 此应用程序使用 TCP 和 UDP 协议。 此应用程序还具有用于消息传递的 GUI。
  • 一个基于UDP协议的文件传输应用程序的实现 简单实用
  • UDP协议应用

    万次阅读 2016-07-21 10:26:15
    介绍了以太网TCP/IP协议族的相关信息,重点介绍了UDP协议使用中应注意的有关问题。

    TCP与UDP:

    1、面向有连接(TCP):

    在发送数据之前,需要在收发主机之间连接一条通信线路。在面向有连接的方式下,必须在通信传输前后,专门进行建立和断开连接的处理。TCP 不提供广播或多播服务,由于 TCP 要提供可靠的、面向连接的传输服务,因此不可避免地增加了许多的开销。这不仅使协议数据单元的首部增大很多,还要占用许多的处理机资源。

    2、面向无连接(UDP):

    面向无连接型则不要求建立和断开连接,发送端可于任何时候自由发送数据。接收端也永远不知道自己会在何时从哪里收到数据,接收端在收到 UDP 报文后,不需要给出任何确认。虽然 UDP 不提供可靠交付,但在某些情况下 UDP 是一种最有效的工作方式。

    UDP是一种无连接的、不可靠的传输层协议,在完成进程到进程的通信中提供了有限的差错检验功能,设计比较简单的UDP协议的目的是希望以最小的开销来达到网络环境中的进程通信目的。

    UDP协议是英文User Datagram Protocol的缩写,即用户数据报协议,主要用来支持那些需要在计算机之间高速传输数据的网络应用。包括网络视频会议系统在内的众多的客户/服务器模式的网络应用都需要使用UDP协议。UDP不失为一项非常实用和可行的网络传输层协议。UDP协议不提供端到端的确认和重传功能,它不保证信息包一定能到达目的地,因此称为不可靠协议。UDP使用IP协议作为数据传输机制的底层协议。

    UDP用户数据报传输过程中的封装与拆封:

                                                                                图1 UDP数据报封装与拆封

    UDP数据报格式:

    UDP报文称为一个用户数据报,它分为两部分:头部和数据区。报文头部中包含有源端口和目的端口、报文长度以及UDP检验和。

    源端口和目的端口(端口是用来指明数据的来源(应用程序)以及数据发往的目的地(同样是应用程序))字段包含了16比特的UDP协议端口号,它使得多个应用程序可以多路复用同一个传输层协议及UDP协议,仅通过端口号来区分不同的应用程序。

    长度(length)字段记录了该UDP数据包的总长度(以字节为单位),包括8字节的UDP头和其后的数据部分。最小值是8(报文头的长度),最大值为65535字节。

    UDP校验和(Checksum)的内容超出了UDP数据报文本身的范围,实际上,它的值是通过计算UDP数据报及一个伪包头而得到的。校验和的计算方法与通用的一样,都是累加求和。

                                                                                                   图2 UDP数据报格式

    UDP检验和的检验范围:

                                                                                        图3 UDP检验和范围

    伪首部并非TCP&UDP数据报中实际的有效成分。伪首部是一个虚拟的数据结构,其中的信息是从数据报所在IP分组头的分组头中提取的,既不向下传送也不向上递交,而仅仅是为计算校验和。

    这样的校验和,既校验了TCP&UDP用户数据的源端口号和目的端口号以及TCP&UDP用户数据报的数据部分,又检验了IP数据报的源IP地址(数据源设备)和目的地址。伪报头保证TCP&UDP数据单元到达正确的目的地址。

    因此,伪报头中包含IP地址并且作为计算校验和需要考虑的一部分。最终目的端根据伪报头和数据单元计算校验和以验证通信数据在传输过程中没有改变而且到达了正确的目的地址。

    UDP数据报在IP报文中的封装:

                                                   图4 UDP封装

    如图所示,在IP数据报中UDP数据报存放于IP首部之后,UDP首部占据了8个字节,之后为UDP数据。

    IP数据报是基于IP的网络中最基本的数据单元形式,在国际互联网络中的众多中间节点路由器,可以识别并转发该种数据报,提供给IP数据报最优的路径选择。具体的IP数据报格式如图5所示:

                                                                                   图5 IP数据报格式

    IP数据报严格划分为多个字段,并且规定了相应字段的内容:

    1)协议版本:4位,表示该IP数据报所采用的具体版本类型,确定是IPv4还是IPv6,目前我们使用的是IPv4版本;

    2)首部长度:4位,可表示的最大数值是15个单位(一个单位是4个字节),首部长度的最小值为5;

    3)服务类型字段:TOS字段,8位,其中第0位至第2位组合表示优先级别第3位至第5位分别表示时延、吞吐量、可靠性,第6为表示最小费用的路由,第7位保留未用;

    4)总长度字段:16位,指的是整个IP数据报的长度,是以字节为单位的,这要区别于首部长度的单位定义,利用首部长度和该字段可以计算出实际的数据内容的起始位置和长度。IP数据报最长可达65535字节,但大多数的网络在传输时都需要对其进行分片,主机也要求不能接收超过576字节的数据报; IP发送模块完成IP协议功能,该模块接收来自传输层的数据单元,然后打包为IP数据报向下层发送。如果待发送的IP数据报的数据长度超过1480个字节,IP发送模块将对该数据报进行分片,其中最后一帧数据长度介于11480个字节。一旦前一帧发送完毕,紧接着发送下一帧。

    5)标识字段:16位,唯一标识主机发送的每一份数据报,通常每发送一份报文它的值就会加1,用于区分不同的分组,便于分片后的重装;

    6)标志字段:FLAG字段,3位,其中第1位表示是否允许分片,第2位表示是否最后一段报文;

    7)生存时间字段:英文缩写为TTL,  8位,设置数据报的生存时间,表示IP数据报最多可以经过的路由器的个数,每经过一个路由器转发数据报,数据报的TTL值就会减1, TTL的初始值由源主机设置,通常设为32或64;

    8)协议字段:IP协议利用该字段对多个IP数据报进行分用,区分是哪一个协议向IP协议传送的字段;协议字段对应的协议如表1所示。

               表1   协议值

    10)首部校验和:16位,根据IP首部计算的检验和码,对一个IP首部进行校验,如果发现数据出现差错,IP就丢弃该数据报,但不产生差错报文,而由上层协议去发现丢失的数据报并进行重传

    11)源IP地址和目的IP地址:均为32位,分别表示数据源主机的IP地址和数据目的主机的IP地址;

    12)任选项:是数据报中的一个可变长的可选信息,该字段一直都以犯位为界限在必要的时候插入值为0的填充字节,保证IP首部始终是32位的整数倍。

    IP分片:

    在TCP/IP分层中,数据链路层用MTU(Maximum Transmission Unit,最大传输单元)来限制所能传输的数据包大小,MTU是指一次传送的数据最大长度,不包括数据链路层数据帧的帧头,如以太网的MTU为1500字节,实际上数据帧的最大长度为1512字节,其中以太网数据帧的帧头为12字节。当发送的IP数据报的大小超过了MTU时,IP层就需要对数据进行分片,否则数据将无法发送成功。

    IP分片发生在IP层,不仅源端主机会进行分片,中间的路由器也有可能分片,因为不同的网络的MTU是不一样的,如果传输路径上的某个网络的MTU比源端网络的MTU要小,路由器就可能对IP数据报再次进行分片。而分片数据的重组只会发生在目的端的IP层。

    在IP首部有4个字节是用于分片的,如下图所示。前16位是IP数据报的标识,同一个数据报的各个分片的标识是一样的,目的端会根据这个标识来判断IP分片是否属于同一个IP数据报。中间3位是标志位,其中有1位用来表示是否有更多的分片,如果是最后一个分片,该标志位为0,否则为1。后面13位表示分片在原始数据的偏移,这里的原始数据是IP层收到的传输的TCP或UDP数据,不包含IP首部。


    需要注意的,在分片的数据中,传输层的首部只会出现在第一个分片中,如下图所示。因为传输层的数据格式对IP层是透明的,传输层的首部只有在传输层才会有它的作用,IP层不知道也不需要保证在每个分片中都有传输层首部。所以,在网络上传输的数据包是有可能没有传输层首部的。需要注意的,在分片的数据中,传输层的首部只会出现在第一个分片中,如下图所示。因为传输层的数据格式对IP层是透明的,传输层的首部只有在传输层才会有它的作用,IP层不知道也不需要保证在每个分片中都有传输层首部。所以,在网络上传输的数据包是有可能没有传输层首部的。


    避免IP分片:

    在网络编程中,我们要避免出现IP分片,那么为什么要避免呢?原因是IP层是没有超时重传机制的,如果IP层对一个数据包进行了分片,只要有一个分片丢失了,只能依赖于传输层进行重传,结果是所有的分片都要重传一遍,这个代价有点大。由此可见,IP分片会大大降低传输层传送数据的成功率,所以我们要避免IP分片。

    对于UDP包,我们需要在应用层去限制每个包的大小,一般不要超过1472字节,即以太网MTU(1500)—UDP首部(8)—IP首部(20)。

    对于TCP数据,应用层就不需要考虑这个问题了,因为传输层已经帮我们做了。在建立连接的三次握手的过程中,连接双方会相互通告MSS(Maximum Segment Size,最大报文段长度),MSS一般是MTU—IP首部(20)—TCP首部(20),每次发送的TCP数据都不会超过双方MSS的最小值,所以就保证了IP数据报不会超过MTU,避免了IP分片。

    展开全文
  • UDP协议

    万次阅读 多人点赞 2017-06-21 12:31:05
    UDP协议UDP协议简介UDP(User Datagram Protocol),用户数据报协议,是OSI(Open System Interconnection,开放式系统互联) 参考模型中一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务,IETF RFC 768...

    UDP协议

    UDP(User Datagram Protocol),用户数据报协议,是OSI(Open System Interconnection,开放式系统互联) 参考模型中一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务,IETF RFC 768是UDP的正式规范。UDP提供了无连接通信,且不对传送数据包进行可靠性保证,适合于一次传输少量数据,UDP传输的可靠性由应用层负责。

    UDP报文没有可靠性保证、顺序保证和流量控制字段等,可靠性较差。但是正因为UDP协议的控制选项较少,在数据传输过程中延迟小、数据传输效率高,适合对可靠性要求不高的应用程序,或者可以保障可靠性的应用程序,如DNS、TFTP、SNMP等。
    UDP在IP报文中的位置如下图所示:
    这里写图片描述
    可以看到,UDP其实就是在IP报文中添加了端口信息,使数据到达主机后送达至相应端口的应用程序。下面是通过wireshark抓的一个UDP数据包:
    在这里插入图片描述


    UDP使用

    在选择使用协议的时候,选择UDP必须要谨慎。在网络质量令人十分不满意的环境下,UDP协议数据包丢失会比较严重。但是由于UDP的特性:它不属于连接型协议,因而具有资源消耗小,处理速度快的优点,所以通常音频、视频和普通数据在传送时使用UDP较多,因为它们即使偶尔丢失一两个数据包,也不会对接收结果产生太大影响。比如我们聊天用的QQ就是使用的UDP协议。

    既然UDP是一种不可靠的网络协议,那么还有什么使用价值或必要呢?其实不然,在有些情况下UDP协议可能会变得非常有用。因为UDP具有TCP所望尘莫及的速度优势。虽然TCP协议中植入了各种安全保障功能,但是在实际执行的过程中会占用大量的系统开销,无疑使速度受到严重的影响。反观UDP由于排除了信息可靠传递机制,将安全和排序等功能移交给上层应用来完成,极大降低了执行时间,使速度得到了保证。


    UDP报头

    UDP报头由4个域组成,其中每个域各占用2个字节,如下图所示:
    这里写图片描述

    • UDP协议使用端口号为不同的应用保留其各自的数据传输通道。UDP和TCP协议正是采用这一机制实现对同一时刻内多项应用同时发送和接收数据的支持。数据发送一方(可以是客户端或服务器端)将UDP数据包通过源端口发送出去,而数据接收一方则通过目标端口接收数据。有的网络应用只能使用预先为其预留或注册的静态端口;而另外一些网络应用则可以使用未被注册的动态端口。*因为UDP报头使用两个字节存放端口号,所以端口号的有效范围是从0到65535。*一般来说,大于49151的端口号都代表动态端口。

    • 数据报的长度是指包括报头和数据部分在内的总字节数。因为报头的长度是固定的,所以该域主要被用来计算可变长度的数据部分(又称为数据负载)。数据报的最大长度根据操作环境的不同而各异。从理论上说,包含报头在内的数据报的最大长度为65535字节。不过,一些实际应用往往会限制数据报的大小,有时会降低到8192字节。(对于一次发送多少字节比较好,后面会讲到)

    • UDP协议使用报头中的校验值来保证数据的安全。校验值首先在数据发送方通过特殊的算法计算得出,在传递到接收方之后,还需要再重新计算。如果某个数据报在传输过程中被第三方篡改或者由于线路噪音等原因受到损坏,发送和接收方的校验计算值将不会相符,由此UDP协议可以检测是否出错。这与TCP协议是不同的,后者要求必须具有校验值。

    • 许多链路层协议都提供错误检查,包括流行的以太网协议,也许你想知道为什么UDP也要提供检查和校验。其原因是链路层以下的协议在源端和终端之间的某些通道可能不提供错误检测。虽然UDP提供有错误检测,但检测到错误时,UDP不做错误校正,只是简单地把损坏的消息段扔掉,或者给应用程序提供警告信息。


    UDP特性

    UDP是一个无连接协议,传输数据之前源端和终端不建立连接,当UDP它想传送时就简单地去抓取来自应用程序的数据,并尽可能快地把它扔到网络上。在发送端,UDP传送数据的速度仅仅是受应用程序生成数据的速度、计算机的能力和传输带宽的限制;在接收端,UDP把每个消息段放在队列中,应用程序每次从队列中读一个消息段。

    由于传输数据不建立连接,因此也就不需要维护连接状态,包括收发状态等,因此一台服务机可同时向多个客户机传输相同的消息。

    UDP信息包的标题很短,只有8个字节,相对于TCP的20个字节信息包的额外开销很小。

    吞吐量不受拥挤控制算法的调节,只受应用软件生成数据的速率、传输带宽、源端和终端主机性能的限制。

    UDP使用尽最大努力交付,即不保证可靠交付,因此主机不需要维持复杂的链接状态表(这里面有许多参数)。

    UDP是面向报文的。发送方的UDP对应用程序交下来的报文,在添加首部后就向下交付给IP层。既不拆分,也不合并,而是保留这些报文的边界,因此,应用程序需要选择合适的报文大小。


    对UDP一次发送多少bytes好?问题的思考

    在进行UDP编程的时候,我们最容易想到的问题就是,一次发送多少bytes好? 当然,这个没有唯一答案。相对于不同的系统,不同的要求,其得到的答案是不一样的。我这里仅对像ICQ一类的发送聊天消息的情况作分析,对于其他情况,或许也能得到一点帮助。

    首先,我们知道TCP/IP通常被认为是一个四层协议系统,包括链路层、网络层、传输层、应用层。UDP属于传输层,下面我们由下至上一步一步来看: 以太网(Ethernet)数据帧的长度必须在46-1500字节之间,这是由以太网的物理特性决定的。 这个1500字节被称为链路层的MTU(最大传输单元)。 但这并不是指链路层的长度被限制在1500字节,其实这个MTU指的是链路层的数据区并不包括链路层的首部和尾部的18个字节。所以事实上这个1500字节就是网络层IP数据报的长度限制。因为IP数据报的首部为20字节,所以IP数据报的数据区长度最大为1480字节。而这个1480字节就是用来放TCP传来的TCP报文段或UDP传来的UDP数据报的。又因为UDP数据报的首部8字节,所以UDP数据报的数据区最大长度为1472字节。这个1472字节就是我们可以使用的字节数。

    当我们发送的UDP数据大于1472的时候会怎样呢? 这也就是说IP数据报大于1500字节,大于MTU。这个时候发送方IP层就需要分片(fragmentation)。把数据报分成若干片,使每一片都小于MTU。而接收方IP层则需要进行数据报的重组。这样就会多做许多事情,而更严重的是,由于UDP的特性,当某一片数据传送中丢失时,无法重组数据报,将导致丢弃整个UDP数据报。因此,在普通的局域网环境下,建议将UDP的数据控制在1472字节以下为好。

    进行Internet编程时则不同,因为Internet上的路由器可能会将MTU设为不同的值. 如果我们假定MTU为1500来发送数据的,而途经的某个网络的MTU值小于1500字节,那么系统将会使用一系列的机制来调整MTU值,使数据报能够顺利到达目的地,这样就会做许多不必要的操作. 鉴于Internet上的标准MTU值为576字节,所以我建议在进行Internet的UDP编程时. 最好将UDP的数据长度控件在548字节(576-8-20)以内.


    UDP协议:低开销通信

    UDP是一种简单协议,提供了基本的传输层功能。与TCP相比,UDP的开销极低,因为UDP是无连接的,并且不提供复杂的重新传输、排序和流量控制机制。

    UDP数据报重组

    与TCP的通信机制不同,由于UDP是无连接协议,因此通信发生之前不会建立会话。UDP是基于事务的,换言之,应用程序要发送数据时,它仅是发送数据而已。很多使用UDP的应用程序发送的数据量很小,用一个数据段就够了。但是也有一些应用程序需要发送大量数据,因此需要用多个数据段。UDP PDU(协议数据单元)的实际意义是数据报,尽管数据段和数据报可以互换使用来描述某个传输层PDU。

    	将多个数据报发送到目的主机时,它们可能使用了不同的路径,到达顺序也可能跟发送时的顺序不同。与TCP不同,UDP不跟踪序列号。UDP不会对数据报重组,因此也不会将数据恢复到传输时的顺序。
    	因此,UDP仅仅是将接收到的数据按照先来后到的顺序转发到应用程序。如果数据的顺序对应用程序很重要,那么应用程序只能自己标志数据的正确顺序,并决定如何处理这些数据。
    

    UDP服务器进程与请求

    与基于TCP的应用程序相同的是,基于UDP的服务器应用程序也被分配了公认端口或已注册的端口。当上述应用程序或进程运行时,它们就会接受与所分配端口相匹配的数据。当UDP收到用于某个端口的数据报时,它就会按照应用程序的端口号将数据发送到相应的应用程序。

    UDP客户端进程

    对于TCP而言,客户端/服务器模式的通信初始化采用由客户端应用程序向服务器进程请求数据的形式。而UDP客户端进程则是从动态可用端口中随机挑选一个端口号,用来作为会话的源端口。而目的端口通常都是分配到服务器进程的公认端口或已注册的端口。

    采用随机的源端口号的另一个优点是提高安全性。如果目的端口的选择方式容易预测,那么网络入侵者很容易就可以通过尝试最可能开放的端口号访问客户端。

    由于UDP不建立会话,因此一旦数据和端口号准备就绪,UDP就可以生成数据报并递交给网络层,并在网络上寻址和发送。

    需要谨记的是,客户端选定了源端口和目的端口后,通信事务中的所有数据报文头都采用相同的端口对。对于从服务器到达客户端的数据来说,数据报头所含的源端口和目的端口作了互换。

    展开全文
  • UDP协议和Ping程序

    千次阅读 2015-04-09 20:50:47
    UDP是一个简单的面向数据...(1)UDP应用程序提交的数据不进行分片处理,分片由IP层负责。 (2)在数据传输过程中延迟小、数据传输效率高,适合对可靠性要求不高的应用程序,或者可以保障可靠性的应用程序,如DNS、

    UDP是一个简单的面向数据报的不可靠的无连接的运输层协议。

    UDP报文格式:
    这里写图片描述

    源端口号:16位。
    目标端口号:16位。
    数据报长度:16位。包含首部和数据。
    检验和:16位。检验覆盖首部和数据部分。

    特点
    (1)UDP对应用程序提交的数据不进行分片处理,分片由IP层负责。
    (2)在数据传输过程中延迟小、数据传输效率高,适合对可靠性要求不高的应用程序,或者可以保障可靠性的应用程序,如DNS、TFTP、SNMP等。
    (3)不提供报文到达确认、排序、及流量控制等功能。
    (4)包括网络视频会议系统在内的众多的客户/服务器模式的网络应用都需要使用UDP协议。

    (好像UDP没有太多好讲的东西。。。)

    Ping程序

    参数:
    - c 数值 :执行Ping的次数。
    - n :不进行IP与主机名的反查,直接使用IP输出(速度更快)。
    - s 数值 :发送出去的ICMP数据包大小,默认为56字节。
    - t 数值:TTL数值,默认是255。
    - W 数值:等待响应对方的秒数。
    - M [do | dont] :主要检测网络的MTU数值大小。do–不可分片;dont–可分片。

    Ping程序通过向目的IP发送ICMP回显请求报文,来测试两个主机的连通性。
    测试步骤:
    1. 使用ipconfig观察本地网络设置是否正确;
    2. Ping127.0.0.1,检查本地的TCP/IP协议有没有设置好;
    3. Ping本机IP地址,这样是为了检查本机的IP地址是否设置有误;
    4. Ping本网网关或本网IP地址,这样的是为了检查硬件设备是否有问题,也可以检查本机与本地网络连接是否正常;
    5.Ping本地DNS地址,这样做是为了检查本地DNS服务器是否工作正常。
    6.Ping远程IP地址,这主要是检查本网或本机与外部的连接是否正常。

    返回信息

    请求超时Request Timed Out:这个信息表示对方主机可以到达到TIME OUT,这种情况通常是为对方拒绝接收你发给它的数据包造成数据包丢失。大多数的原因可能是对方装有防火墙或已下线。
    目标网络不可达Destination Net Unreachable:这个信息表示对方主机不存在或者没有跟对方建立连接。这里要说明一下”destination host unreachable”和”time out”的区别,如果所经过的路由器的路由表中具有到达目标的路由,而目标因为其它原因不可到达,这时候会出现”time out”,如果路由表中连到达目标的路由都没有,那就会出现”destination host unreachable”。
    坏的IP地址Bad IP address: 这个信息表示你可能没有连接到DNS服务器所以无法解析这个IP地址,也可能是IP地址不存在。
    Source quench received信息比较特殊,它出现的机率很少。它表示对方或中途的服务器繁忙无法回应。

    展开全文
  • 主要介绍了使用C#实现基于TCP和UDP协议的网络通信程序的示例,文中分别编写了基本的服务器端和客户端,代码十分简单,需要的朋友可以参考下
  • TCP协议和UDP协议的区别及其应用

    万次阅读 多人点赞 2018-07-02 19:34:45
    下面是TCP和UDP的简单程序: 简单的TCP网络程序 ...简单的UDP网络程序 https://blog.csdn.net/qq_37941471/article/details/80726398 接着我们通过这两个协议来更直接的理解一下TCP协议和UDP协议: 这两个协议...

    下面是TCP和UDP的简单程序:
    简单的TCP网络程序
    https://blog.csdn.net/qq_37941471/article/details/80738319
    简单的UDP网络程序 https://blog.csdn.net/qq_37941471/article/details/80726398
    接着我们通过这两个协议来更直接的理解一下TCP协议和UDP协议:
    这两个协议其实都属于传输层协议。
    这里写图片描述

    UDP协议


    1. UDP协议端的格式 :

    这里写图片描述
    `

    1. 传输层向应用层交付的过程:解包和分用
    2. 如何将有效载荷和报头分离?
     情况一:在应用层中,http协议是通过一个空行来当做分隔符
     情况二: 在下三层(传输层,网络层,数据链路层)中,
            都是通过报头定长的方式来实现报头和数据有效分离。
            这里的报头标准长度为:8字节
    3. 传输层中为什么会有源端口号和目的端口号?
       向应用层交付过程中需要端口号来找到应用层的处理程序(进程)
       ( ip地址+端口号(套接字)能够标识网络上的某台主机放入某个进程 )
    4. 16位UDP长度:
       表示整个数据报的最大长度。而这个数据报指的是:UDP首部 + UDP数据
    5. 16位UDP校验和:
       如果校验和出错,就会直接丢弃
       另外我们可以看出源端口号和目的端口号都是用16位来表示,
       所以说端口号的大小是两个字节(16位),是协议规定的。

    2. UDP的特点 :

    1. 无连接:
       知道服务器端的IP和端口号就直接进行传输,不需要建立连接(图一);
       图一是没有运行服务器端,直接运行客户端的情况,
       输出内容,收不到服务器端的回应,处于等待阻塞等待状态。
       而tcp是需要连接的,图二就是不运行服务器端直接运行客户端的情况:连接失败
    2. 不可靠:
       没有确认机制,没有重传机制;如果因为网络故障该段报文无法发到对方,
       UDP协议层也不会给应用层返回任何的错误信息。
    3. 面向用户数据报:
       不能够灵活的控制读写数据的次数和数量
          那么,udp在传输中,会不会出现只发送了一半的报文的情况?
          答:不会。因为应用层交给UDP多长的报文,UDP会原样发送,
              既不会拆分,也不会合并(整包收整包发).
    4. 简单快速(高效):
       不会因为维护可靠性而花费时间及成本。
    5. 另外传输的数据有上限,64k

    图一:
    这里写图片描述
    图二:
    这里写图片描述

    3. UDP的缓冲区 :

    UDP的socket既能读又能写,即全双工。

    没有真正意义上的发送缓冲区:
        调用sendto()会直接将报文交给内核, 
        由内核将数据传给网络层协议进行后续的传输工作;
    具有接受缓冲区:
         但是它不能保证UDP报文收到的顺序和发送的顺序一致; 
         并且如果缓冲区满了,接下来到达的报文会被丢弃。
    

    4. 基于UDP的应用层协议 :

    1. NFS:网络文件系统
    2. TFTP:简单文件传输协议
    3. DHCP:动态主机配置协议
    4. BOOTP:启动协议(用于无盘设备启动)
    5. DNS:域名解析协议
      当然也包括自己写的UDP程序中自定义的应用层协议。

    TCP协议:


    和UDP协议(没有真正意义上的发送缓冲区,具有接受缓冲区)对比,TCP协议是具有接受缓冲区和发送缓冲区的。

    1. TCP协议段格式 :

    这里写图片描述

    1. 源/目的端口号:表示的是从哪来到哪里去
                     为了保证将该报文传到传输层的某一个应用程序(进程)
    2. 32位序号/32位确认序号:图中已经说明,而其目的就是:保证报文能够按序到达
    3. 4位TCP报头长度:表示该TCP头部的最大长度是15*4=60
        其中一行代表4个字节,而标准的报头是前5行(20个字节;
        而第六行的选项是头部选项,占用40个字节。一共加起来就是60个字。
    4. 6位标志位:
       URG: 表示紧急指针是否有效。(通常将其数据称为:带外数据) 
            如果想优先处理那个数据,就将这个标志位置为1
       ACK: 表示确认号是否有效。我们称携带ACK标志的TCP报文段为确认报文段。 
            如果确认,就有可能带着要发送的内容
       PSH: 提示接收端应用程序应该立即从TCP接受缓冲区中读走数据(按序处理),为接受  
            后续数据腾出空间,如果不将接收到的数据读走,它们就会一直停留在TCP报文段。 
       RST: 表示要求对方重新建立连接。我们称携带RST标志的TCP报文段为复位报文段。
            如果服务器端并没有收到请求连接,那么就将这个RST标志位置为1,表示客户端  
            重新请求连接。(告诉客户端连接失败,这个时候有可能做两件事: 
            1.重新建立连接 2.断开之前的连接)
       SYN: 表示请求建立一个新连接。称携带SYN标志位的TCP报文段为同步报文段。
            只有请求连接的时候,ACK=0,这个时候需要收到对方的应答, 
            如果收到了,就会将ACK = 1.
       FIN: 表示通知对方本端要关闭连接了。称携带FIN标志的TCP报文段为结束报文段。 
    5. 16位窗口大小:图中有讲
    6. 16位校验和:由发送端填充,接收端对TCP报文端执行CRC算法以检验TCP报文段  
                 在传输过程中是否损坏(检验部分包括报头和数据部分)。 
    7. 16位紧急指针:图中有讲,并且将其要处理的数据叫做:带外数据
    8. 选项:40字节的头部选项字段

    2. TCP协议的特点 :

    总体来说TCP协议会比较复杂,因为要保证可靠性,同时又尽可能的去提高性能。
    1. 有连接
       UDP协议知道服务器端的IP和端口号就直接进行传输,不需要建立连接(图一);
       图一是没有运行服务器端,直接运行客户端的情况,  
       输出内容,收不到服务器端的回应,处于等待阻塞等待状态。 
       而tcp是需要连接的,图二就是不运行服务器端直接运行客户端的情况:连接失败
    2. 可靠传输
    3. 面向字节流

    图一:
    这里写图片描述
    图二:
    这里写图片描述

    tcp协议最重要的特点:
    可靠性:
      1. 校验和
      2. 面向连接
      3. 接受和发送 请求确认 确认应答
      4. 序列号(报文按序到达)
      5. 去重(超时重传中按照序列号实现去重)
      6. 连接管理
      7. 流量控制
      8. 拥塞控制
      9. 面向连接
    提高性能:
      1. 滑动窗口
      2. 快速重传
      3. 延迟应答
      4. 捎带应答
      其实拥塞控制主要体现了可靠性,但其实也提高了性能
    协议中出现的3个定时器 :
      1. 超时重传定时器
      2. 保活定时器
      3. TIME_WAIT定时器题

    下面我们针对上面的问题做以解释:

    3. 连接管理机制 :

    在我的另外一篇文章的最底下有讲TCP协议的通讯过程:
    https://blog.csdn.net/qq_37941471/article/details/80738319#t6

    另外:

    在正常情况下,TCP是要经过三次握手建立连接,四次挥手 断开连接。
    并且,服务器端和客户端不管是在收发报文时,都是基于状态机的。

    4. 理解TIME_WAIT状态 :


    两方建立连接,如果服务器端先断开连接,而客户端还开着;然后立即重启服务器端,会发现端口地址被占用,无法建立连接,因为主动断开连接的一方有一个等待的过程 ( TIME_WATE )。

    服务器先断开连接后:

    这里写图片描述
    这里写图片描述

    我们会发现,突然间断开服务器,而客户端还在连接中,立即重启服务器是不可以的!等一会才可以再次重启服务器。这是等一会的时间就是在四次挥手(断开连接)的时间。

    我们用netstat命令看一下:
    这里写图片描述

    1. TCP协议规定,主动关闭连接的一方要处于TIME_WAIT状态,
       等待两个MSL(报文最大生存时间)的时间后才能回到CLOSE状态。
    2. 我们使用ctrl+c 终止了server,所以server是主动关闭连接的一方,在TIME_WAIT期间仍然不能再次监听同样的server端口
    3. MSL在RFC1122中规定为两分钟,但是各操作系统的实现不同,在Centos7默认配置的值是60s.
       可以通过下面的命令来查看msl的值:
       [root@localhost day03_6.18]# cat /proc/sys/net/ipv4/tcp_fin_timeout
        60
       [root@localhost day03_6.18]# 
    
    解决TIME_WAIT状态失败引起的bind失败的方法:

    使用setsockopt( )设置socket描述符的SO_REUSEADDR为1,表示允许创建端口号相同但ip地址不同的多个socket描述符。
    在Tcp_server.c代码的socket( ) 和 bind( ) 调用之间插入如下代码:

     int opt = 1;
     setsockopt(listen_sock,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));
         int listen_sock = socket(AF_INET, SOCK_STREAM , 0 );// SOCK_DGRAM 表示UDP
         if(listen_sock < 0)
         {   
             perror("socket");
             return 2;
         }
         printf("Socker:%d\n",listen_sock);
    
         int opt = 1;
         setsockopt(listen_sock,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));
        //2. 命名套接字
    
        struct sockaddr_in local;
        local.sin_family = AF_INET;
        local.sin_port = htons(atoi(argv[2]));//端口号是2位的数
        local.sin_addr.s_addr = htonl(INADDR_ANY);//INADDR_ANY可以绑定任意ip
    

    这里写图片描述
    我们会发现,突然间断开服务器,而客户端还在连接中,立即重启服务器是可以的。

    5. 确认应答机制:


    数据( 序列号 ):TCP将每个字节的数据都进行了编号,即为序列号,比如下面的1~1000
    确认序列号:每一个ACK都带有对应的确认序列号,告诉发送者,下次应该从哪一个报文开始发。
    比如下面的:下一个是1001,这就是确认序列号
    1

    6. 超时重传机制:


    主机A没有收到主机B的确认应答,有两种情况:

    1. 主机B没有收到数据:主机A向主机B发送数据过程中,由于网络拥堵等原因,数据无法到达主机B(解决方法:在一个特定的时间内,主机A没有收到B发来的确认应答,就会重发数据)

    这里写图片描述

    2. 主机B收到数据,但是ACK丢失了:

    这样如果主机A重发数据,主机B会收到很多重复的数据,那么TCP协议将如何识别这些重复的包,并且将重复的包丢弃呢?
    答:根据之前协议中的字段:序列号,很容易就会实现去重的效果

    这里写图片描述

    3. 那么如何确定这个超时的时间?

    随着网路环境的不同,是有差异的;TCP为了保证无论在任何环境下都能比较高性能的通信,因此动态计算这个最大的超时时间。

    7. 滑动窗口:


    1. 为什么需要滑动窗口?

    答: 提高性能。
            原因:每一个发送出去的数据段,都要收到一个ACK确认应答,
                 收到之后再发送下一个数据段;这样数据多的时候,性能会较差。
     如何提高性能:一次发送多条数据。(将串行改成并行)

    2. 窗口大小和16位窗口大小的区别:
    这里写图片描述

    1. 窗口大小:指的是无需等待确认应答而可以继续发送数据的最大值。
               ( 上图中的窗口大小就是:4000个字节 )
    2. 16位窗口大小:是告诉对方自己的接受能力
    3. 窗口大小:是根据接收端的接收能力(16位窗口大小)而定的窗口大小
    
    1. 发送前4段的时候,不需要等待任何的ACK,直接发送;
    2. 收到第一个ACK后,滑动窗口自动向后移动,继续发送第5段的数据;
       依次类推( 如下图 ,下图中是根据数组的下标来确定滑动窗口的大小的)
    3. 操作系统内核如何维护滑动窗口?
       答:发送端维护:开辟一个发送缓冲区,来记录哪些数据还没有应答
                     只有确认应答过的数据才能从缓冲区中删除。
    4. 窗口越大,网络的吞吐率就越高。

    这里写图片描述

    8. 如果出现了丢包,如何进行重传?&& 快速重传机制 :


    1. 报文比较多,为了提高性能使用滑动窗口的情况下:
    
    情况一 :数据已经抵达,ACK(确认信息)丢了
    
    这种情况就是:一个滑动窗口的大小是4000,前面的3000的确认信息(ACK)某个丢失了,
    但是收到了(下一个是4001)的信息,这种情况其实表示主机B已经收到了前4000个数据,
    这种ACK丢失没有影响。 
    
    情况二:数据报直接丢了(如下图)
          这种机制被称为“高速重发控制”(也叫作“快重传”)
          1. 怎么会触发快重传机制?
          答:如果发送端连续收到3次一样的确认应答信息
          2. 触发快重传机制后怎么做?
          答:立即重传。并且下一次收到的ACK根据之前的传送情况来决定(如下图的情况)
    
    2. 如果只有一两个报文,根本就不会触发快重传机制:
    
       因为:快重传机制要收到3个同样的确认应答,才会触发快重传机制。
            这个时候应该触发的是:超时重传机制。

    这里写图片描述

    9. 流量控制:


    1. 为什么需要流量控制?

    答: 因为接收端的接受能力(能够处理的数据)是有限的;
        而发送端如果发送的太快的话,接受缓冲区很容易就会被装满;
        这个时候如果发送端继续发送数据的话,则会出现丢包问题。
        继而会出现丢包重传等一些问题;
        所以我们就需要流量控制机制,来防止这种情况发生。
    

    2. 流量控制的概念:

    TCP支持根据接受端的处理能力,来决定发送端发送数据的速度,这种机制叫做流量控制(Flow control)
    3. 怎么做到流量控制 ?:

    TCP首部的16位窗口大小的含义就是告诉发送端自己的接受能力
    
    1. 接受端 :将自己可以接收的缓冲区大小放入TCP首部的"16位窗口大小"中;
              然后通过ACK通知发送端。
              如果一旦发现自己的缓冲区变少了,就将窗口大小的值变小;
    2. 发送端 :根据对方的"16位窗口大小"来控制自己的发送速度;
              如果发现窗口大小变小了,就减慢自己的速度;
    3. "16位窗口大小"和 网络的吞吐量成正比 :
              窗口大小字段的值越大,网络的吞吐量就越高,传输效率就越高
    4. 接收端 :如果发现接受缓冲区满了,就将窗口大小置为0
    5. 发送端 :这个时候发送端看到之后,就不会再去发送数据( 防止丢包 )
               而这个时候,发送端需要定期的去探测接受端;将自己的窗口大下高速发送端

    具体的实现过程如下图:
    这里写图片描述
    4. 16位的数字大小是65535,那么TCP窗口大小最大65535吗?

    答: 不是。
       TCP首部里面有一个选项,选项中包含了一个窗口扩大因子M;
       实际上的窗口大小最大是:窗口字段左移M位;
       当然最后的结果肯定是小于等于65535的

    10. 拥塞控制:


    1. 为什么要拥塞控制?

    答:因为TCP在为了提高效率:
       1. 根据接收端的接收能力("16位窗口大小")来确定发送端的滑动窗口大小
    
       而又为了可靠性,即可靠高效的传送大量的数据时 :
       1. 我们需要考虑网络状态
       2. 如果网络拥塞,贸然的去发送大量的数据,必定会丢包,丢大量的数据
    
       根据丢包的多少,来确定是哪里出了问题?
       1. 丢失了少量的数据 :我们会认为是发送端发错了,漏发了,这个时候进行(重传处理)
       2. 丢失了大量的数据 :那么就有可能是网络拥塞的可能;
                          如何避免这种情况,引出了拥塞控制机制

    2. 怎么进行拥塞控制?

    1. 首先:先发少量的数据,去摸清当前网络的拥塞状态
    2. 再决定按照多大的速度来传输数据
      这里写图片描述
    一切的基础还是慢开始,这种方法的思路是这样的:
    
     1. 发送方维持一个叫做“拥塞窗口”的变量
        该变量和接收端的窗口大小共同决定了发送者的发送速度;
    
     2. 当主机开始发送数据时,避免一下子将大量字节注入到网络,
        造成或者增加拥塞,选择发送一个1字节的试探报文;
    
     3. 当收到第一个字节的数据的确认后,就发送2个字节的报文;
    
     4. 若再次收到2个字节的确认,则发送4个字节,依次递增2的指数级;
    
     5. 最后会达到一个提前预设的“慢开始门限”,
       比如24,即一次发送了24个分组,此时遵循下面的条件判定:
    
       *1. cwnd < ssthresh, 继续使用慢开始算法;
    
       *2. cwnd > ssthresh,停止使用慢开始算法,改用拥塞避免算法;
    
       *3. cwnd = ssthresh,既可以使用慢开始算法,也可以使用拥塞避免算法;
    
     6. 所谓拥塞避免算法就是:每经过一个往返时间RTT就把发送方的拥塞窗口+1,
                           即让拥塞窗口缓慢地增大,按照线性规律增长;
    
     7. 当出现网络拥塞,比如丢包时,将慢开始门限设为原先的一半,
        然后将cwnd设为1,执行慢开始算法(较低的起点,指数级增长);

    3. 发送数据时,需要考虑哪两个方面?

    1. 接收端的"16位窗口大小"( 即接受端的接受能力 ) :
       根据窗口大小,来确定滑动窗口大小,并且还能通过流量控制来实现可靠性
    2. 考虑网络的拥塞情况 :
       根据拥塞窗口,来控制传输的速度
    总结:我们借用滑动窗口来提高效率的时候,同时需要:流量控制 和 拥塞控制
         来维护可靠性,从而实现高效又可靠的传输。

    11. 延迟应答:


    1. 目的:

    1. 提高效率
    2. 为了给发送端回应一个更大的"16位窗口大小"
       (窗口大小越大,网络的吞吐量就越大,传输的效率也就越高)

    2. 如果立即应答,会怎么样?:

    1. 如果接收缓冲区的大小为1M,而一次只收到了500K的数据,
       这个时候如果立即应答,发送端接收到的窗口大小就是500K(接收缓冲区剩余的空间)
    2. 而如果延迟应答,等一会,有可能应用层的处理端会很快的处理缓冲区的数据,
       那么我们回应给发送端的窗口大小就是1M.

    3. 是不是所有的包都可以延迟应答?

    我们的目的就是提高效率,然后如果所有的包都延迟应答的话,有可能反而起到了反的作用
    
    这个时候,我们应该怎么把我延迟应答的时间呢?
    1. 数量限制 :每隔N个包,延迟应答一次
    2. 时间限制 :每隔一段时间,延迟应答一次
     而这个时间根据操作系统的不同,时间也不同;
     一般N取2;时间取200ms

    12. 捎带应答:


    1. 目的:提高效率
    2. 什么情况下需要捎带应答?

     当客户端和服务器端在应用层“一发一收”的时候
     比如 :
     客户端 :how are you?
     服务器端 : Fine,thank you!
     这个时候,服务器端给客户端的确认应答ACK可以搭一个顺风车,
             同"Fine,thank you!"一起回给客户端

    这里写图片描述

    13. 面向字节流:


    TCP的一个连接,具体发送缓冲区,又有接受缓冲区;
    并且对于一个连接,既可以读数据,又可以写数据;这个概念叫做全双工。
    
    由于缓冲区的存在,TCP程序的读和写不需要一一匹配
    1.100个字节的数据 :
       1. 可以调用一次的write,直接一次写入100个字节
       2. 也可以调用100次的write,一次写入1个字节
    2.100个字节的数据 :
       不考虑写入的时候是怎么写入的
       1. 可以调用一次的read,直接一次读100个字节
       2. 也可以调用100次的read,一次读1个字节

    14. 粘包问题:


    1. 为什么会有粘包问题?

    1. UDP的报头中有一个"16位的报文长度"的字段,这样会很明确的清楚数据的边界
       而TCP的报头没有这个字段
    2. 站在传输层的角度 :
       TCP是一个报文一个报文按照顺序放在缓冲区中的
    3. 站在应用层的角度 :
       看到的只是一连串连续的字节数据。无法确认边界

    2. 如何避免粘包问题?

    明确边界
    1. 对应定长的包 :保证每次都按照固定的大小去读取
       比如Request结构,就是固定大小的;
       每次读取的时候,都是从头开始读取一个sizeof(Request)的大小
    2. 对于变长的包 :
       1. 可以在包头的位置,约定一个包总长度的字段,从而知道包的结束位置
       2. 当然也可以在包与包之间用分隔符来分界
        (这个是由应用层实现的,也属于一个自己的应用层协议)

    3. 对于UDP协议来说,会不会出现粘包问题?

    答: 不会。
        1. 首先,UDP协议的报头中有一个"16位的报文长度"的字段,
                这样会很明确的清楚数据的边界
        2. 其次,UDP协议是面向数据报的,它是整包收整包发的
                既不能拆分,又不能合并;不会出现"半个"的情况

    15. TCP异常情况:


    1. 进程终止 :进程终止会释放文件描述符,仍然可以发送FIN(四次挥手),
                 和正常关闭没有什么区别;
    2. 机器重启 :和进程终止的情况相同
    3. 机器断电/网络断开:
         1. 比较突然的情况,接收端会认为连接还在,
           一旦接收端有写入操作,会发现连接已经不再了,就会进行reset.
         2. 即使没有写入操作,TCP自己也内置了一个保活定时器,会定期的询问对方还在不在;
            如果不在的话,就会把连接关闭,释放。(这个不会有四次挥手)
    

    16. 基于TCP的应用层协议:


    1. HTTP
    2. HTTPS
    3. SSH
    4. Telnet
    5. FTP
    6. SMTP

    TCP/UDP对比:


    我们说TCP是可靠连接,那么TCP就一定优于UDP吗?
    答: 不是的。
         根据应用场景,来选择更优的协议
         1. TCP协议的应用 :用于可靠传输的情况
                          比如:文件传输,重要状态更新的场景
         2. UDP协议的应用 :用于高效传输和实时性要求较高的通信领域
                          比如:早期的QQ,视频传输,另外还可以用于广播

    UDP不能实现可靠性,但是如何实现呢?

    通过应用层来实现(谁有谁来实现)


    展开全文
  • 基于zynq板卡的vivado工程中对网口部分调用udp协议应用实例
  • UDP协议学习

    2021-02-24 07:07:47
    UDP(UserDatagramProtocol),用户数据报协议,是...但是正因为UDP协议的控制选项较少,在数据传输过程中延迟小、数据传输效率高,适合对可靠性要求不高的应用程序,或者可以保障可靠性的应用程序,如DNS、TFTP、SNMP
  • 一个UDP协议的聊天室源程序,基于VB.Net2005开发,程序最先确定本地、远程计算机通信端口,然后初始化程序,启动侦听线程,此时你就可以发送消息了,程序主要是为了展示UDP的应用程序其实相当简单,供VB的新手参考...
  • 基于UDP协议的网络通信应用程序(UDP-Socket) 前两篇文章介绍了基于TCP/IP协议的网络通信应用程序。 嵌入式Linux应用程序开发-(7)TCP-IP网络通信应用程序(TCP-Client) 嵌入式Linux应用程序开发-(8)TCP-IP...
  • udp 协议

    千次阅读 2011-11-29 17:00:54
    我们知道,ip协议提供了在主机之间交互数据的机制,udp协议则提供应用程序之间传输数据报的基本机制,也就是说udp协议能够区分在同一台机器上运行的多个程序或进程。udp协议通过在ip协议上添加端口来实现此目的,...
  • UDP协议功能

    千次阅读 2019-05-24 15:11:53
    1、使用UDP协议包括:TFTP、SNMP、NFS、DNS UDP使用底层的互联网协议来传送报文,同IP一样提供不可靠的无连接数据报传输服务。它不提供报文到达确认、排序、及流量控制等功能。 2、UDP的报报文格式 每个UDP报文分UDP...
  • 协议系列之UDP协议

    千次阅读 2014-08-21 21:53:40
    这节要讨论的就是UDP协议,它提供了更加快的发送速度,但也牺牲了可靠性,它是一种无连接的传输协议。比起TCP,UDP更像是我们用手机发送短信,只管发送出去,但不能保证对方收到,不会建立连接,也没有确认环节。 图...
  • UDP协议详解

    千次阅读 2020-12-25 14:39:47
    2、UDP协议 3、端口 4、UDP和ARP之间的交互 5、UDP适用场景 6、UDP洪水 1、简介 UDP(UserDatagramProtocol)是一个简单的面向消息的传输层协议,尽管UDP提供标头和有效负载的完整性验证(通过校验和),但它...
  • Java使用UDP协议收发数据简单实现

    万次阅读 2015-08-07 18:24:05
    UDP简介1.UDP 是User Datagram Protocol的简称, 中文名是用户数据报协议!简单Java代码实现!适合初学!
  • 基于TCP的应用协议 与基于UDP应用协议分别有哪些
  • UDP 协议解析

    2020-02-11 21:25:52
    用户数据报协议UDP,User Datagram Protocol)为应用程序提供了一种无需建立连接就可以发送封装的 IP 数据报的方法。UDP是一种保留消息边界的简单的面向数据报的协议UDP不提供差错纠正、队列管理、重复消除、...
  • UDP协议和TCP协议

    千次阅读 2020-07-03 18:26:45
    UDP协议和TCP协议都是传输层的协议,TCP协议提供可靠的通信传输,而UDP则是常常被用于让广播和细节控制的交给应用的通信传输 UDP协议:不保证安全,但是性能比较好 UDP的传输过程类似于寄信,仅仅在乎的是信件有...
  • udp协议基础

    千次阅读 2017-05-09 15:38:34
    什么是UDP协议  UDP协议就是一种无连接的协议。该协议用来支撑那些需要在计算机之间传输数据的网络应用,  包括网络视频会议系统在内的众多客户端/服务器模式的网络应用  udp的主要作用就是将网络数据流量压缩成...
  • 终于把TCP协议与UDP协议给整明白了

    万次阅读 多人点赞 2020-07-04 21:35:16
    网络编程有三个要素,分别是IP地址、端口号和通信协议,本文主要讲述的是TCP与UDP这两种通信协议,以及编程的实现。
  • udp协议简介

    千次阅读 2007-12-21 13:50:00
    包括网络视频会议系统在内的众多的客户/服务器模式的网络应用都需要使用UDP协议UDP协议从问世至今已经被使用了很多年,虽然其最初的光彩已经被一些类似协议所掩盖,但是即使是在今天,UDP仍然不失为一项非常实用和...
  • TCP协议与UDP协议的区别

    千次阅读 2020-08-21 10:04:01
    TCP协议与UDP协议的区别 首先咱们弄清楚,TCP协议和UDP协议与TCP/IP协议的联系,很多人犯糊涂了, 一直都是说TCP协议与UDP协议的区别,我觉得这是没有从本质上弄清楚网络通信! TCP/IP协议是一个协议簇。里面包括...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 175,371
精华内容 70,148
关键字:

使用udp协议的应用程序