在我们开始学习网络编程的时候,我们发现一些名词出现的频率极其高,比如 TCP/IP、UDP、OSI  七层网络模型等。这肯定不是偶然,因为它们极其重要,才会被人反复提及。尤其在面试的时候,面试官喜欢把它们拿来,当作考察面试者基础功底的重要环节。为了不让文章显得冗余,我们今天只谈网络中的  TCP、UDP 和端口。

协议、TCP 和 UDP

在了解 TCP(Transmission Control Protocol 即传输控制协议) 和 UDP(User Datagram Protocol  即用户数据包协议)  之前,我们先要知道一个名词,即协议。它到底是什么?它其实就是一套约定成俗的规则。就像开会的时候,我们达成了一些共识,先开发那个接口,项目什么时候上线等等。

可以毫不夸张地说计算机网络的构建与发展,奠基石就是各种网络协议。它们定义了信息通讯的方式,以及如何收发信息等,比如:

  • IP 协议负责将多个包交换网络连接起来,并管理通讯 IP 源地址和目标地址的协议

  • TCP 和 UDP 协议则是位于应用层和 IP 层之间,负责它们之间信息传输的重要协议

既然是协议,大家都必须遵守,否则,今天张三定一个协议,李四不同意,他明天再定一个协议,这就乱了套。因此,不同的大厂和许多公司就联合起来组成一个组织,将这些协议统一规范起来。你就必须得用这些规定好的协议,否则就无法通信。这才实现了“地球村”的梦想。今天无论用什么设备,在世界的任何角落,用哪种国家的语言,都可以很方便地使用网络进行通信。

TCP 和 UDP 的特点

用一个不算严谨的说法总结 TCP 就是,女孩子如果遇到 TCP  这样的男生,就嫁了吧。因为TCP的核心特点就是靠谱。他的特定包括,面向连接、可靠、基于字节流控制的传输,就像一个管道一样将应用层和 IP 层连接起来。

而与之相对应的,UDP  就像二十多岁的浪子。他们不够可靠,但却充满热情。一切以效率为先,他们可以马上答应你很多事情,并且愿意立马付出实践。你这一秒说佛珠浪漫,他不管身处何处,立马搭飞机给你去取,下一秒说想去听周杰伦的演唱会,他立马给你订票。当然,人的精力和时间都有限,所以就可能出现不可控的意外,比如根本没有足够的钱买门票等。这和UDP相仿,它提供无连接通信,但不对传送的数据包提供可靠性保证。

TCP 和 UDP 的特点总结

TCP 和 UDP 的特点总结

TCP 和 UDP 的使用场景

不同的人,因性格不同,做事的方式也不一样,你不能说这样就一定好,那样就一定不好,对于 TCP 和 UDP  也是一样,在不同的场景中,他们各有各的妙用。

比如在开发一个游戏的的程序是,对于玩家登陆账号,因为我们要确保不同的玩家能登陆到自己的账号,这个时候就要应用 TCP  协议。而对于控制游戏中角色的移动,我们只需根据玩家鼠标的点击移动角色,如果因为小概率的网络问题,对于玩家来说,再次进行角色移动操作即可,成本和风险在可控范围内,因此就可以使用  UDP 协议。

我们从以上可以看出,如果是基础服务功能,则最好使用 TCP 协议,保证服务的可靠性。以确保过程中,每一个网络包能够正确抵达目的地。而相较于 UDP  ,程序员则需要自己去进一步做丢包情况和字节传输顺序的处理。

可不要因此就觉得 UDP 非常难用,正相反,其实有大量的服务是基于 UDP 协议的。比如 DNS 解析服务。每一台电脑访问外网网页,都需要通过 DNS  服务解析域名,从中找到对应的 IP 地址。这个时候如果 DNS 出了问题,我们其实只需要再一次进行 DNS  寻址查询即可。唯一的副作用,可能就是有一丁点儿延迟罢了。

另一个 UDP 的应用就是 IP 电话, 我们常把它称作 VoIP(Voice over  IP),它的原理可以简化的理解为,把拨打电话从以往的电话通讯,转移到网络通讯上,类似于我们现在的微信通话。当你和某人通话的时候,用的就是 UDP  ,想象一下,其实我们这个时候需要的并不是可靠性,而是实时性。如果不幸中间有一点信息损失了,比如你妈说:“过年给我把对象带回来,不然就别回来了”。由于信息损失一部分,像这样——“过年给  把对象带 来,不然 别回 了”,其实我们是可以理解一整句话的意思的。而如果用 TCP,我们可能说一句话,别人 30 秒之后才能听到,这显然是不能忍受的。

因此,我们明白了,在日常的开发过程中,我们应该根据不同的应用场景,选择对应的 TCP 或者 UDP 作为网络传输协议,而不能因为我们对 UDP  不熟悉,就从心理上抗拒它。

端口及其特点

如果 IP  是用来定位街区的,那么端口就是对应于该街区中每一户的门牌号。在通讯过程中,数据通过各种通讯协议最终抵达设备(如计算机)后,这里的设备就相当于一个街区,而在设备计算机内部有很多程序在跑,数据进来之后,必须要给它一个对应的门牌号(即端口号),程序才方便进行后续操作。

端口号属于传输协议的一部分,因此我们可以说,数据通过 IP 地址发送对应的数据到指定设备上,而通过端口号把数据发送到指定的服务或程序上。

程序一般不止是监听指定的端口号,而且也会明确对应的传输协议。所以我们在进行数据传输的时候,既要指定对应的端口号,也要指定对应的通讯协议,很多人仅仅会说:程序  A 监听着 33001 端口,这个是不正确的,至少是不完全正确的。相应的,我们应该这样说:程序 A 使用 TCP 协议,监听 33001  端口,当然你也可以说:程序 A 使用 UDP 协议,监听 33001 端口。

指定传输协议和端口,显而易见的好处在于,当我们进行端口转发或者构建网络防火墙的时候,我们可以很方便的通过协议和端口进行隔离。以防止不可预见的意外发生。对于计算机来说,通过这种方式可以防止外网各种不必要的数据,进入本地局域网。

你可能会想,这么多端口号,如果大家都用同一个,那不是也有冲突。没错,这就需要一个专门的组织来管理它们,IANA( Internet Assigned  Numbers Authority 即互联网号码分配局 ),它负责管理端口注册。大多数主流的程序,都有一个明确的已注册端口,比如常见的 FTP 监听 20、  21 端口,而 HTTP 服务监听 80 端口等。如果有一个程序想注册某个端口,那么 IANA  会先去查一查这个端口是否已被注册,如果已经被注册了,它则会拒绝申请。

端口号根据范围分为三种

1. Well-Known Ports(即公认端口号)

它是一些众人皆知著名的端口号,这些端口号固定分配给一些服务,我们上面提到的 HTTP 服务、  FTP服务等都属于这一类。知名端口号的范围是:0-1023。

2. Registered Ports(即注册端口)

它是不可以动态调整的端口段,这些端口没有明确定义服务哪些特定的对象。不同的程序可以根据自己的需要自己定义,注册端口号的范围是:1024-49151。

3. Dynamic, private or ephemeral ports(即动态、私有或临时端口号)

顾名思义,这些端口号是不可以注册的,这一段的端口被用作一些私人的或者定制化的服务,当然也可以用来做动态端口服务,这一段的范围是:49152–65535。