TCP、UDP及Socket(Port)的关系,深入浅出!

提醒:貌似这里说的socket是指port,而非socket api技术!仅供参考!貌似标题命名不准确的说
《更安全的Linux网络》第1章防火墙的基本概念,在本书的开始将详尽讲解与防火墙相关的TCP/IP技术。此外,对于防火墙的原理、种类、架构及其优、缺点,在本章中也都有详尽的介绍。本节为大家介绍TCP、UDP及Socket的关系。
1.4 TCP、UDP及Socket的关系
在了解了信息在网络上是如何传递之后,接下来,我们要认识传输层中另一个重要的标记——Port。Port在传输层中是一个很重要的概念,我们之所以能够在一台主机上同时执行多个服务,都得归功于Port的概念。在开始谈Port之前,我们先来了解什么是Socket。
Socket是指一个上面有很多“洞”的东西,比如说,计算机主机板上CPU的插座,我们称其为Socket 478或Socket 939等,而Socket上面这些洞在传输层中则称为Port,在OS的网络系统中会有两个Socket,分别为TCPSocket及UDP Socket,Socket上各有65536个洞,我们把它称为Port 0、Port 1、Port 2 …… Port 65 535。
我们以图1-11为例来说明Port的用途,图的左边为Client端、图的右边则为Server端,在Server端主机上,我们假设执行了Web、 SSH及DNS这3项服务,在 TCP/IP的网络规范中,每一个网络应用程序执行时都会占用一个Port,如Server端的Web Service启动时,就会占用在TCP Socket中的Port80,简称为TCP Port 80,而SSH Service是TCP Port 22、DNS Service则为UDP Port 53,因此我们可以说,TCP Port 80代表Web Service程序,TCPPort 22代表SSH Service程序,而UDP Port 53即代表DNS Service程序。
    

图1-11  TCP、UDP及Port的关系
另外,在Client部分,我们假设Client端启动了Browser、SSH Client及DNS Client 这3个网络应用程序,在TCP/IP的规范中,客户端的网络应用程序启动时,一样也会占用一个Port。如图1-11所示,我们假设Browser使用 TCP Port 2099、SSH Client使用TCP Port 2088,以及DNS Client使用UDPPort 5555,因此,我们也可以说,TCP Port 2099代表Browser程序、TCPPort 2088代表SSH Client程序、而UDP Port 5555则代表DNS Client程序。接下来看Port的用途。假设Client端主机上的Browser欲与Server端的Web Service 来传递数据,因此,Client端主机随即产生一个数据封包送至 Server 端。我们假设 Client 端的 IP 为 10.0.1.219、Server 端的 IP 为202.43.195.52,这个封包的内容就如图1-12所示。首先,封包内必然会记录封包的来源及目的,在图1-12中所标记的部分即为封包的来源 及目的地址,但光是这两项信息只能代表Client端及Server端在传送数据,并无法说明Client端主机上哪一个应用程序在访问,所标记的部分就 说明了Client端以Port 2099来连接Server端的Port 80,但别忘了刚才说过的,Port可以代表主机上目前正在执行的某一个应用程序。

    

图1-12  Client送至Server的封包内容
从以上说明我们可以了解,系统在接到一个封包之后,它是如何来辨别这个数据封包是要送给哪一个应用程序的。
当Web Service接到这个请求封包之后,Web Service也会回应Client端主机一个封包,而这个封包的内容就如图1-13所示,图中③所标记的位置为来源及接收端主机的IP,标记④的位置则 表示来源端的Web Service(Port 80)及响应给Client端主机的浏览器(Port 2099)。由以上例子相信你已经了解了Port的用途。
  
  
图1-13  Server回应Client的封包内容
在了解Port的用途之后,我们要了解65536个Port是如何被分配使用的。其实,不管是TCP Port或UDP Port的运用,在RFC 1700文档中都有完整的规范,我们可以从IANA的网站(http://www.iana.org/assignments/port-numbers)中取得Port的使用列表,或是从Linux系统中的/etc/services文件中取得这些信息,笔者将其整理如下。
公认的Port:0~1023。 
注册的Port:1024~49 151。 
动态的Port:49 152~65 535。 
1. 公认的Port
会使用TCP Port 80,因为它是一个“规范”、是大家都知道的事,所以Client端在Web Server上访问Web Service时,Client端就会预设将封包送至Web Server的TCP Port 80。也因为有规范的存在,所以我们要访问远程的某个服务时,就无须特别打电话去询问:“你们家的Web Service是使用在哪个Port中”,换句话说,每个Service都会有一个固定的Port,而这些Port我们就称为公认的Port,其范围为 0~1023。
2. 注册的Port
由于在同一时间内,相同的Port只能给一个程序使用,因此,程序设计师在编写网络应用程序时,就得特别注意自己开发的应用程序是使用哪一个Port,而 这个Port是否已经被其他的应用程序占用了,但问题是程序设计师如何得知该Port已被其他应用程序占用了呢?所幸的是IANA组织定了一个规范,为了 避免不必要的Port冲突,在指定Port之前,凡是需要用到固定Port的网络应用程序可先在IANA的网站上选用一个没有其他应用程序在使用的 Port,并且可以将其注册下来,以告诉其他的程序设计师,某个Port已被你所选用且已被注册,通过IANA机制即可避免Port冲突的问题,而这些可 被使用者注册的Port范围为1024~49 151。
3. 动态的Port
动态的Port通常应用在暂时性的使用上,例如,几乎所有Client端的应用程序都会使用动态Port,在Client端的应用程序启动时,系统就会分 配一个“动态的Port”给该应用程序使用,并且在应用程序结束时将Port归还给系统,而这些动态的Port范围为49 152~65 535。
请注意,以上所讲的“规范”并非所有程序设计师都会遵循,比如说,Linux系统上的SSH Client所使用的Port通常都会落在“注册的Port”范围内,其实这并不会对系统造成什么问题。原则上,“相同一个Port在同一时间内不得有一 个以上的应用程序同时使用”,只要把握这个原则,基本上都是可以被接受的。