三十天学不会TCP,UDP/IP网络编程-UDP,从简单的开始
如果对和程序员有关的计算机网络知识,和对计算机网络方面的编程有兴趣,欢迎去gitbook(https://www.gitbook.com/@rogerzhu/)star我的这一系列文章,虽然说现在这种“看不见”的东西真正能在实用中遇到的机会不多,但是我始终觉得无论计算机的语言,热点方向怎么变化,作为一个程序员,很多基本的知识都应该有所了解。而当时在网上搜索资料的时候,这方面的资料真的是少的可怜,所以,我有幸前两年接触了这方面的知识,我觉得我应该把我知道的记录下来,虽然写的不一定很好,但是希望能给需要帮助的人多个参考。我的计划是用半年时间来写完这一系列文章,这个标题也是我对太多速成文章的一种态度,好了,废话不再多扯了,下面是其中的一节内容,更多内容可以去gitbook上找到。
从这一节开始就进入传输层的部分了,也是内容最丰富可能更贴近于实际的部分了,很多书籍会从TCP开始介绍传输层,我觉得学习应该从简单的到难的,所以我选择从UDP先开始,况且是现有UDP协议并且发展至成熟然后再有的TCP。
UDP协议历史
如果有人问我他想阅读RFC,也就是我前面提过的互联网的标准,有啥推荐的着手点。标准这种玩意儿大部分都又枯燥又长,真要看,睡着了是必须的,不看吧,总感觉与人谈论的时候少了一种老子当年也是参加过啥啥的感觉。所以如果真想看看RFC到底都写些啥,怎么写,我十分推荐原始的UDP标准作为一个开始,UDP的RFC号是768,一共就3页,完整而又严谨的阐述了UDP协议,虽然是英文,全看一遍也就最多30分钟吧,而且有图有真相,有文字有引用,作为一个着手点再合适不过。
UDP协议,学名User Datagram Protocol,Datagram这个名词第一次在网络中是在1970年,在一个很早期的网路设计CYCLADES中被一个叫Louis Pouzin提出。这个词是data和telegram的一个组合,而这个CYCLADES是一个保证在可靠传输data而不保证可靠传输网络的设计,简单的来说就是这个网络设计保证从放到一个端口上传出去的数据可以完整无误的到达另一端但是不保证一端想要传输的数据都能可靠的被放在端口上或者被另一端取出。这个Louis Pouzin提出这样一个想法的原因之一就是他并不喜欢事情搞得很复杂,他认为没有必要在一个已经具有可靠传输的机制上再叠加一层可靠传输的端到端的设计。
从目前看这个想法虽然是有弊端的,但是在当时并没有那么大的网络负载和网络架构的时候,这是一种经济而又行之有效的办法,所以Datagram这个想法就被IP协议的设计者们所借鉴。
UDP特点
就如上一节所描述,Datagram提供的是一种不可靠的协议传输,最简单的不可靠就是从A端的传输层发出的数据包不保证B端能接收到,或者按需要收到,B端也无需向A端表明自己是否收到。这有点像以前有一种群寄广告的方法,寄广告的一方并不知道他寄出的地址的人有没有收到自己寄出去的广告,而收到广告更没必要向寄出的人表明自己收到与否。
本质上为什么称UDP为不可靠呢?因为他并不会保存发送出去的备份,这个特点在UDP中导致会有以下几个方面的表现:
- 不能保证传送出去的数据包不丢失,不重复
- 不能保证传送出去的一系列数据包在接收端还是以相同的顺序被读取
- 不能保证传送出去的数据包不出错
另外UDP也没有拥塞控制,这个专业名词到TCP的时候会详细描述,其实就是当路上流量很大甚至被堵的完全走不动的时候,UDP协议会不管这些东西,继续向网络上发送数据包。这样会引起很多不良后果,比如丢包,造成网络整个的崩溃。
那么UDP有这么多弱点为什么还作为传输层两巨头之一被广泛运用呢?因为其长处也很明显,就是经济。所谓经济就是UDP没有复杂的建立连接,重传重排,拥塞避免(这些名词后面都会成为主角)等等,他只管在一端把数据发出去,同等情况下相对于要做这么多额外工作的协议肯定要快一些且“经济”一些,那么有的应用对于数据包短暂丢失,乱序,错乱都是能够忍受的。最能理解的应用应该是网络视频,网络电话之类的,对于一两帧的丢失并不会引起用户的抱怨。当然除了视频,还有很多协议是建立在UDP之上的,他们中有的已经退出历史舞台,有的依然天天都会为我们的上网默默的做出你看不到的工作,比如DHCP,DNS。甚至还有由于其没有连接性的特点不得不使用UDP的场景,就是传输层广播。
UDP数据包头
UDP是工作在IP之上的,是一个应用层到IP的简单接口,所以UDP整个的数据包是放在IP data部分的(可以回去再复习一下IP数据包头格式)。而UDP数据包头被设计的及其简单而又有效,整个包头只有8个字节,分为四个部分。这里我要用RFC里面的原图了,这里我不得不说RFC里的图是我最佩服的部分之一,各种各样的图示都用字符来绘画出来,有的真的可以说让我叹为观止。
从低字节到高字节依次是源端口,目的地端口,数据包长度,CRC校验和。
如果让我选传输层第一关键词,我会选端口,应用层的各种协议的最重要的标识物之一就是传输层的端口。为什么在IP地址上还要加上端口这个概念呢?第一个作用是可以让一个主机上的应用层可以有标识进行IP地址的复用,第二个就是分层思想里最重要的,每一层都处理每一层的事情,链路层看到MAC地址就知道这是链路层的数据包,网络层看到IP地址或者类似的地址就知道自己该干活了,传输层也是一个道理。这样数据才能沿协议栈不断的上传,而每一层也可以干自己的事情。
所以类似IP数据包头有自己和对端的IP地址一样,在UDP数据包头中会含有自己的源端口号和对方的端口号。不过由于UDP是不需要对方返回响应消息的,所以源端口号可以填0表示不填。一个端口号是16位,所以一个IP地址最大的端口号是65535,但是很多端口号都是预先被保留用做特定的用途,这个在传输层杂项中我再稍微详细的介绍一下。
接下来按照我前面所介绍的记这种数据头格式的重要部分,就是长度,因为你需要让对方知道我该读多少的数据。
接下来的CRC校验和比较有趣了,IP包头的效验和是头部校验和,只有头部的数据会参与计算。而在UDP里,这个校验和采用了一个伪头部的概念。所谓伪头部就是UDP在计算效验和的时会把IP头部的一些信息加入计算,具体的就是如下的信息:
其中包括,源IP地址,目的地IP地址,填充的8位0,协议名(UDP),UDP报文长度,为什么要这么做呢,标准里的解释是通过IP地址可以确认该数据包是不是发送给本机,通过协议,可以确认有没有误传。这样做的好处是很明显的,一是可以再一次确认关键字段没有错误,而是使用伪首部而不是真正的把这些数据放在UDP数据包里可以减少负担。
但是这个设计违背们一直强调的分层思想,在传输层不应该混入网络层的东西,而且在网络层的头数据包CRC中已经让两个IP地址参与计算过了,这里再进行一次校验,看起来有点多余。而我对这个问题也一直不知道最深的设计原理是什么,我的理解是可能在分层思想的时候隐含着虽然每一层都做自己的事情,但是上一层不应该天然相信下一层,在需要的时候他也可以对下一层的某些关键信息再做双层确认。
对于这个校验和,因为UDP是不保证可靠性的,在IPv4中是可以不填的,而以我遇到过的例子来看,大部分是不填的,或者填了对端也不会检验的,所谓多一事不如少一事的哲学思维看来也是通用的。
UDP数据实例
按照风格,再一次让我们来看看现实抓包中的UDP数据包头是什么样子的。
这个图中可以看到,UDP是建立在IP纸上的,这里的源端口号是68,目的地端口号是67,长度329,这里开启了checksum但是对端也不会确认计算的。最后一个stream index 是wireshark内部的编号,用来标识UDP,TCP数据流的序号,用中括号括起来的都不是UDP数据包中真正的内容。
好了,UDP就是这么简单的一个协议,但是用处却是很广泛,从下一节开始,就从不同的几个方面来介绍下UDP在每一台电脑上都会做的几件事情。
三十天学不会TCP,UDP/IP网络编程-UDP,从简单的开始的更多相关文章
- 三十天学不会TCP,UDP/IP网络编程 - UDP的实践--DHCP
在经历了一顿忙碌加出去玩了玩之后,我又开始重新更新了~这是最新的一篇~完整版可以去gitbook(https://www.gitbook.com/@rogerzhu/)看到,在gitbook的后台流量 ...
- 三十天学不会TCP,UDP/IP网络编程-IP头格式祥述
我又来了,这篇文章还是来做(da)推(guang)介(gao)我自己的!俗话说事不过三,我觉得我下次得换个说法了,不然估计要被厌恶了,但是我是好心呐,一定要相信我纯洁的眼神.由于这两年接触到了比较多的 ...
- 三十天学不会TCP,UDP/IP网络编程-ARP -- 连接MAC和IP
继续来做(da)推(guang)介(gao)我自己的!由于这两年接触到了比较多的这方面的知识,不想忘了,我决定把他们记录下来,所以决定在GitBook用半年时间上面写下来,这是目前写的一节,目前已完成 ...
- 三十天学不会TCP,UDP/IP编程--MAC地址和数据链路层
这篇文章主要是来做(da)推(guang)介(gao)的!由于这两年接触到了比较多的这方面的知识,不想忘了,我决定把他们记录下来,所以决定在GitBook用半年时间上面写下来,这是目前写的一节,后面会 ...
- 三十天学不会TCP,UDP/IP网络编程-TraceRoute的哲学
新年快乐,继续来部分粘贴复制我的这一系列文章啦,如果对和程序员有关的计算机网络知识,和对计算机网络方面的编程有兴趣,欢迎去gitbook(https://www.gitbook.com/@rogerz ...
- 三十天学不会TCP,UDP/IP网络编程 - 绅士的开始
经过了过年的忙碌和年初的懈怠一切的日子,我又开始重新更新了~这是最新的一篇~完整版可以去gitbook(https://www.gitbook.com/@rogerzhu/)看到. 如果对和程序员有关 ...
- 三十天学不会TCP,UDP/IP网络编程 - RST的用法
不知不觉也写了这么多了,继续我的自己的推广大业~完整版可以去gitbook(https://www.gitbook.com/@rogerzhu/)看到. 如果对和程序员有关的计算机网络知识,和对计算机 ...
- 三十天学不会TCP,UDP/IP网络编程 -- TCP中的智慧之连续ARQ
突然发现上一篇文章贴图有问题,关键我怎么调也调不好,为了表达歉意,我再贴一篇gitbook上的吧,虽然违背了我自己的隔一篇在这里发一次的潜规则~其余完整版可以去gitbook(https://www. ...
- 三十天学不会TCP,UDP/IP网络编程 -- RTT的计算
欢迎去gitbook(https://www.gitbook.com/@rogerzhu/)看到完整版. 如果对和程序员有关的计算机网络知识,和对计算机网络方面的编程有兴趣,虽然说现在这种“看不见”的 ...
随机推荐
- 原生JS—实现图片循环切换及监测鼠标滚动切换图片
今天我们主要讲讲如何使用原生JS实现图片的循环切换的方法以及如何检测鼠标滚动循环切换图片.多余的话我们就不多说了,我们一个一个开始讲吧. 1 原生JS实现图片循环切换 -- 方法一 在上栗子之前我们 ...
- 最简单的optparse模块的用法
optparse模块是python自带的模块,可用于处理命令行 #!/usr/bin/env python # -*- coding: utf-8 -*- """ __a ...
- Maven依赖分析
背景 昨天帮一位同事排查了一个依赖冲突的问题.问题的现象就是在IntelliJ IDEA运行项目正常,但是打包(Maven assembly jar)之后传到服务器运行失败,报错:Caused by: ...
- nodejs+mongoose+websocket搭建xxx聊天室
简介 本文是由nodejs+mongoose+websocket打造的一个即时聊天系统:本来打算开发一个类似于网页QQ类似功能的聊天系统,但是目前只是开发了一个模块功能 --- 类似群聊的,即一对多的 ...
- JS 函数节流和去抖
1.什么是节流和去抖? 节流.就是拧紧水龙头让水少流一点,但是不是不让水流了.想象一下在现实生活中有时候我们需要接一桶水,接水的同时不想一直站在那等着,可能要离开一会去干一点别的事请,让水差不多流满一 ...
- Apache服务器配置
之前做代码一直按照传统化的方法部署别人的网站,但是一直不成功,尝试了很多次最后才发现时虚拟主机的问题 使用apache默认为127.0.0.1和网站的配置发生冲突. 因此在apache的conf文件夹 ...
- mysql安装简单教程(自动安装/配置安装)
mysql安装简单教程(自动安装/配置安装) 1.1前言: 由于特殊原因,在最近2-3个月里mysql真是安装了无数遍,每次安装都要上网找教程,每个教程基本都不一样,因此还是自己写下来比较好,毕竟自己 ...
- SEO中TDK写法的意思以及注意事项
在SEO中,所谓的TDK其实就是title.description.keywords这三个标签,这三个标签在网站的优化过程中,至关重要所以今天童童来和大家分享下,如何去写好TDK标签! 1.title ...
- javascript设计模式——单例模式
前面的话 单例模式是指保证一个类仅有一个实例,并提供一个访问它的全局访问点. 单例模式是一种常用的模式,有一些对象往往只需要一个,比如线程池.全局缓存.浏览器中的window对象等.在javaScri ...
- javascript设计模式——发布订阅模式
前面的话 发布—订阅模式又叫观察者模式,它定义对象间的一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知.在javascript开发中,一般用事件模型来替代传统的发布—订阅模 ...