其他
UDP,你要耗子喂汁呀!
The following article is from 程序员cxuan Author cxuan
运输层概述
TCP 和 UDP 前置知识
怎么计算机网络中的术语对一个数据的描述这么多啊? 在计算机网络中,在不同层之间会有不同的描述。我们上面提到会将运输层的分组称为报文段,除此之外,还会将TCP中的分组也称为报文段,然而将 UDP的分组称为数据报,同时也将网络层的分组称为数据报。
套接字
套接字类型
数据报套接字(Datagram sockets):数据报套接字提供一种无连接的服务,而且并不能保证数据传输的可靠性。数据有可能在传输过程中丢失或出现数据重复,且无法保证顺序地接收到数据。数据报套接字使用UDP(User DatagramProtocol)协议进行数据的传输。由于数据报套接字不能保证数据传输的可靠性,对于有可能出现的数据丢失情况,需要在程序中做相应的处理。 流套接字(Stream sockets):流套接字用于提供面向连接、可靠的数据传输服务。能够保证数据的可靠性、顺序性。流套接字之所以能够实现可靠的数据服务,原因在于其使用了传输控制协议,即TCP(The Transmission Control Protocol)协议 原始套接字(Raw sockets): 原始套接字允许直接发送和接收IP数据包,而无需任何特定于协议的传输层格式,原始套接字可以读写内核没有处理过的IP数据包。
套接字处理过程
socket中的API用于创建通信链路中的端点,创建完成后,会返回描述该套接字的套接字描述符。
就像使用文件描述符来访问文件一样,套接字描述符用来访问套接字。
当应用程序具有套接字描述符后,它可以将唯一的名称绑定在套接字上,服务器必须绑定一个名称才能在网络中访问 在为服务端分配了socket并且将名称使用bind绑定到套接字上后,将会调用listen api。listen 表示客户端愿意等待连接的意愿,listen 必须在accept api之前调用。 客户端应用程序在流套接字(基于TCP)上调用connect发起与服务器的连接请求。 服务器应用程序使用acceptAPI接受客户端连接请求,服务器必须先成功调用bind和listen后,再调用accept api。 在流套接字之间建立连接后,客户端和服务器就可以发起read/write api调用了。 当服务器或客户端要停止操作时,就会调用 close API 释放套接字获取的所有系统资源。
聊聊 IP
提高网络扩展性:实现大规模网络互联 对应用层和链路层进行解藕,让二者独立发展。
我们知道,TCP协议的下一层就是IP协议层,既然IP不可靠,那么如何保证数据能够准确无误地到达呢?
端口号
为了方便资源的使用,提高机器的性能、利用率和稳定性等等原因,我们的计算机都有一层软件叫做操作系统,它用于帮我们管理计算机可以使用的资源,当我们的程序要使用一个资源的时候,可以向操作系统申请,再由操作系统为我们的程序分配和管理资源。 通常当我们要访问一个内核设备或文件时,程序可以调用系统函数,系统就会为我们打开设备或文件,然后返回一个文件描述符fd(或称为ID,是一个整数),我们要访问该设备或文件,只能通过该文件描述符。可以认为该编号对应着打开的文件或设备。
周知/标准端口号,它的范围是0-1023 注册端口号,范围是1024-49151 私有端口号,范围是49152-6553
确定端口号
标准既定的端口号
时序分配的端口号
多路复用和多路分解
无连接的多路复用和多路分解
面向连接的多路复用与多路分解
UDP
UDP特点
速度快,采用UDP协议时,只要应用进程将数据传给UDP,UDP就会将此数据打包进UDP报文段并立刻传递给网络层,然后TCP有拥塞控制的功能,它会在发送前判断互联网的拥堵情况,如果互联网极度阻塞,那么就会抑制TCP的发送方。使用UDP的目的就是希望实时性。 无须建立连接,TCP在数据传输之前需要经过三次握手的操作,而UDP 则无须任何准备即可进行数据传输。因此UDP没有建立连接的时延。如果使用TCP和UDP来比喻开发人员:TCP就是那种凡事都要设计好,没设计不会进行开发的工程师,需要把一切因素考虑在内后再开干!所以非常靠谱;而UDP就是那种上来直接干干干,接到项目需求马上就开干,也不管设计,也不管技术选型,就是干,这种开发人员非常不靠谱,但是适合快速迭代开发,因为可以马上上手! 无连接状态,TCP需要在端系统中维护连接状态,连接状态包括接收和发送缓存、拥塞控制参数以及序号和确认号的参数,在UDP中没有这些参数,也没有发送缓存和接受缓存。因此,某些专门用于某种特定应用的服务器当应用程序运行在 UDP上,一般能支持更多的活跃用户 分组首部开销小,每个TCP报文段都有20字节的首部开销,而UDP仅仅只有8字节的开销。
这里需要注意一点,并不是所有使用UDP协议的应用层都是不可靠的,应用程序可以自己实现可靠的数据传输,通过增加确认和重传机制。所以使用 UDP协议最大的特点就是速度快。
UDP报文结构
源端口号(Source Port) :这个字段占据UDP报文头的前16位,通常包含发送数据报的应用程序所使用的UDP端口。接收端的应用程序利用这个字段的值作为发送响应的目的地址。这个字段是可选项,有时不会设置源端口号。没有源端口号就默认为0 ,通常用于不需要返回消息的通信中。 目标端口号(Destination Port): 表示接收端端口,字段长为16位 长度(Length): 该字段占据16位,表示UDP数据报长度,包含UDP报文头和UDP数据长度。因为UDP报文头长度是8个字节,所以这个值最小为8,最大长度为65535字节。 校验和(Checksum):UDP使用校验和来保证数据安全性,UDP的校验和也提供了差错检测功能,差错检测用于校验报文段从源到目标主机的过程中,数据的完整性是否发生了改变。发送方的UDP对报文段中的16比特字的和进行反码运算,求和时遇到的位溢出都会被忽略,比如下面这个例子,三个16比特的数字进行相加
下面来想一个问题,为什么UDP会提供差错检测的功能?
文件从主机A传到主机B,也就是说AB主机要通信,需要经过三个环节:首先是主机A从磁盘上读取文件并将数据分组成一个个数据包packet,,然后数据包通过连接主机A和主机B的网络传输到主机B,最后是主机B收到数据包并将数据包写入磁盘。在这个看似简单其实很复杂的过程中可能会由于某些原因而影响正常通信。比如:磁盘上文件读写错误、缓冲溢出、内存出错、网络拥挤等等这些因素都有可能导致数据包的出错或者丢失,由此可见用于通信的网络是不可靠的。 由于实现通信只要经过上述三个环节,那么我们就想是否在其中某个环节上增加一个检错纠错机制来用于对信息进行把关呢? 网络层肯定不能做这件事,因为网络层的最主要目的是增大数据传输的速率,网络层不需要考虑数据的完整性,数据的完整性和正确性交给端系统去检测就行了,因此在数据传输中,对于网络层只能要求其提供尽可能好的数据传输服务,而不可能寄希望于网络层提供数据完整性的服务。