《UNIX网络编程 卷1:套接字联网API(第3版)》——2.9 端口号

2.9 端口号

任何时候,多个进程可能同时使用TCP、UDP和SCTP这3种传输层协议中的任何一种。这3种协议都使用16位整数的端口号(port number)来区分这些进程。

当一个客户想要跟一个服务器联系时,它必须标识想要与之通信的这个服务器。TCP、UDP和SCTP定义了一组众所周知的端口(well-known port),用于标识众所周知的服务。举例来说,支持FTP的任何TCP/IP实现都把21这个众所周知的端口分配给FTP服务器。分配给简化文件传送协议(Trivial File Trqnsfer Protocol,TFTP)的是UDP端口号69。

另一方面,客户通常使用短期存活的临时端口(ephemeral port)。这些端口号通常由传输层协议自动赋予客户。客户通常不关心其临时端口的具体值,而只需确信该端口在所在主机中是唯一的就行。传输协议的代码确保这种唯一性。

IANA(the Internet Assigned Numbers Authority,因特网已分配数值权威机构)维护着一个端口号分配状况的清单。该清单一度作为RFC多次发布;RFC 1700[Reynolds and Postel 1994]是这个系列的最后一个。端口号被划分成以下3段。

(1)众所周知的端口为 0~1023。这些端口由IANA分配和控制。可能的话,相同端口号就分配给TCP、UDP和SCTP的同一给定服务。例如,不论TCP还是UDP端口号80都被赋予Web服务器,尽管它目前的所有实现都单纯使用TCP。

端口号80分配时SCTP尚不存在。新的端口分配将针对这3种协议执行,RFC 2960则声明所有现有的TCP端口号对于使用SCTP的同一服务同样有效。

(2)已登记的端口(registered port)为1024~49151。这些端口不受IANA控制,不过由IANA登记并提供它们的使用情况清单,以方便整个群体。可能的话,相同端口号也分配给TCP和UDP的同一给定服务。例如,6000~6063分配给这两种协议的X Window服务器,尽管它的所有实现当前单纯使用TCP。49151这个上限的引入是为了给临时端口留出范围,而RFC 1700[Reynolds and Postel 1994]所列的上限为65535。

(3)49152~65535是动态的(dynamic)或私用的(private)端口。IANA不管这些端口。它们就是我们所称的临时端口。(49152这个魔数是65536的四分之三。)

图2-10展示了端口号的划分情况和常见的分配情况。

我们要注意图2-10中以下几点。

Unix系统有保留端口(reserved port)的概念,指的是小于1024的任何端口。这些端口只能赋予特权用户进程的套接字。所有IANA众所周知的端口都是保留端口,分配使用这些端口的服务器(例如FTP服务器)必须以超级用户特权启动。
由于历史原因,源自Berkeley的实现(从4.3BSD开始)曾在1024~5000范围内分配临时端口。这在20世纪80年代初期是可行的,但是如今很容易就找到一个在任何给定时间内同时支持多于3977个连接的主机。于是许多较新的系统从另外的范围分配临时端口以提供更多的临时端口,它们或者使用由IANA定义的临时端口范围,或者使用一个更大的其他范围(如图2-10所示的Solaris)。
由于这个原因,许多较早的系统实现的临时端口范围的上限为5 000。5 000这个上限后来发现是一个排版错误[Borman ],本应该是50 000。

有少数客户(而不是服务器)需要一个保留端口用于客户/服务器的认证:rlogin和rsh客户就是常见的例子。这些客户调用库函数rresvport创建一个TCP套接字,并赋予它一个在513~1023范围内未使用的端口。该函数通常先尝试绑定端口1023,若失败则尝试1022,依次类推,直到在端口513上亦或成功,亦或失败。
注意:BSD的保留端口和rresvport函数都跟IANA众所周知端口的后半部分重叠。这是因为IANA众所周知端口早先的上限为255。1992年的RFC 1340(早先的一个"Assigned Numbers"RFC)开始在256~1023之间分配众所周知的端口。1990年的RFC 1060(更早先的一个"Assigned Numbers"RFC)称256~1023之间的端口为Unix标准服务(Unix Standard Services)。20世纪80年代有不少源自Berkeley的服务器在512以后挑选它们的众所周知的端口(留下256~511这个空档)。rresvport函数选择从1023开始往下寻找,直至513。

套接字对
一个TCP连接的套接字对(socket pair)是一个定义该连接的两个端点的四元组:本地IP地址、本地TCP端口号、外地IP地址、外地TCP端口号。套接字对唯一标识一个网络上的每个TCP连接。就SCTP而言,一个关联由一组本地IP地址、一个本地端口、一组外地IP地址、一个外地端口标识。在两个端点均非多宿这一最简单的情形下,SCTP与TCP所用的四元组套接字对一致。然而在某个关联的任何一个端点为多宿的情形下,同一个关联可能需要多个四元组标识(这些四元组的IP地址各不相同,但端口号是一样的)。

标识每个端点的两个值(IP地址和端口号)通常称为一个套接字。

我们可以把套接字对的概念扩展到UDP,即使UDP是无连接的。当讲解套接字函数(bind、
connect、getpeername等)时,我们将指明它们在指定套接字对中的哪些值。举例来说,bind函数要求应用程序给TCP、UDP或SCTP套接字指定本地IP地址和本地端口号。

时间: 2024-09-15 10:07:53

《UNIX网络编程 卷1:套接字联网API(第3版)》——2.9 端口号的相关文章

UNIX网络编程:通用套接字选项

1. SO_BROADCAST 套接字选项 本选项开启或禁止进程发送广播消息的能力.只有数据报套接字支持广播,并且还必须是在支持广播消息的网络上(例如以太网,令牌环网等).我们不可能在点对点链路上进行广播,也不可能在基于连接的传输协议(例如TCP和SCTP)之上进行广播. 2. SO_DEBUG 套接字选项 本选项仅由TCP支持.当给一个TCP套接字开启本选项时,内核将为TCP在该套接字发送和接受的所有分组保留详细跟踪信息.这些信息保存在内核的某个环形缓冲区中,并可使用trpt程序进行检查. 3

socket-unix网络编程环境怎么配置?我买了套接字联网api和tcp/ip详解,但是书上的代码都不能运行.

问题描述 unix网络编程环境怎么配置?我买了套接字联网api和tcp/ip详解,但是书上的代码都不能运行. 就下面这个代码,运行提示没有unp.h,找了个unp.h,但是还是提示什么各种数据类型重复定义.我到现在觉得是不是这本书写错了. #include "unp.h" int main(int argc, char **argv) { int sockfd, n; char recvline[MAXLINE + 1]; struct sockaddr_in servaddr; if

《UNIX网络编程 卷1:套接字联网API(第3版)》——导读

**前言**本书面向的读者是那些希望自己编写的程序能使用称为套接字(socket)的API进行彼此通信的人.有些读者可能已经非常熟悉套接字了,因为这个模型几乎已经成了网络编程的同义词,但有些读者可能仍需要从头开始学习.本书想达到的目标是向大家提供网络编程指导.这些内容不仅适用于专业人士,也适用于初学者:不仅适用于维护已有代码,也适用于开发新的网络应用程序:此外,还适用于那些只是想了解一下自己系统中网络组件的工作原理的人. 书中的所有示例都是在Unix系统上测试通过的真实的.可运行的代码.但是,考

《UNIX网络编程 卷1:套接字联网API(第3版)》——1.8 BSD网络支持历史

1.8 BSD网络支持历史 套接字API起源于1983年发行的4.2BSD操作系统.图1-15展示了各种BSD发行版本的发展史,并注明了TCP/IP的主要发展历程.1990年面世的4.3BSD Reno发行版本随着OSI协议进入BSD内核而对套接字API做了少量的改动. 图1-15中从4.2BSD往下到4.4BSD的通路展示了源自Berkeley计算机系统研究组(Computer Systems Research Group,CSRG)的各个版本,它们要求获取者已拥有Unix的源代码许可权.然而

《UNIX网络编程 卷1:套接字联网API(第3版)》——1.10 Unix标准

1.10 Unix标准 在编写本书时,最引人注目的Unix标准化活动是由Austin公共标准修订组(The Austin Common Standards Revision Group,CSRG)主持的.他们的努力结果是涵盖1 700多个编程接口的约4 000页内容的规范[Josey 2002].这些规范既具有IEEE POSIX名字,也具有开放团体的技术标准(The Open Group's Technical Standard)名字.其结果是同一个Unix标准有多个名字来指称:ISO/IEC

《UNIX网络编程 卷1:套接字联网API(第3版)》——2.6 TCP连接的建立和终止

2.6 TCP连接的建立和终止 为帮助大家理解connect.accept和close这3个函数并使用netstat程序调试TCP应用,我们必须了解TCP连接如何建立和终止,并掌握TCP的状态转换图. 2.6.1 三路握手建立一个TCP连接时会发生下述情形. (1)服务器必须准备好接受外来的连接.这通常通过调用socket.bind和listen这3个函数来完成,我们称之为被动打开(passive open). (2)客户通过调用connect发起主动打开(active open).这导致客户T

《UNIX网络编程 卷1:套接字联网API(第3版)》——2.3 用户数据报协议(UDP)

2.3 用户数据报协议(UDP) UDP是一个简单的传输层协议,在RFC 768[Postel 1980]中有详细说明.应用进程往一个UDP套接字写入一个消息,该消息随后被封装(encapsulating)到一个UDP数据报,该UDP数据报进而又被封装到一个IP数据报,然后发送到目的地.UDP不保证UDP数据报会到达其最终目的地,不保证各个数据报的先后顺序跨网络后保持不变,也不保证每个数据报只到达一次. 我们使用UDP进行网络编程所遇到的问题是它缺乏可靠性.如果一个数据报到达了其最终目的地,但是

《UNIX网络编程 卷1:套接字联网API(第3版)》——1.5 一个简单的时间获取服务器程序

1.5 一个简单的时间获取服务器程序 我们可以编写一个简单的TCP时间获取服务器程序,它和1.2节中的客户程序一道工作.图1-9给出了这个服务器程序,它使用了上一节中讲过的包裹函数. 创建TCP套接字10 TCP套接字的创建与客户程序相同. 把服务器的众所周知端口捆绑到套接字11~15 通过填写一个网际套接字地址结构并调用bind函数,服务器的众所周知端口(对于时间获取服务是13)被捆绑到所创建的套接字.我们指定IP地址为INADDR_ANY,这样要是服务器主机有多个网络接口,服务器进程就可以在

《UNIX网络编程 卷1:套接字联网API(第3版)》——1.11 64位体系结构

1.11 64位体系结构 20世纪90年代中期到未期开始出现向64位体系结构和64位软件发展的趋势.其原因之一是在每个进程内部可以由此使用更长的编址长度(即64位指针),从而可以寻址很大的内存空间(超过232字节).现有32位Unix系统上共同的编程模型称为ILP32模型,表示整数(I).长整数(L)和指针(P)都占用32位.64位Unix系统上变得最为流行的模型称为LP64模型,表示只有长整数(L)和指针(P)占用64位.图1-17对这两种模型进行了比较. 从编程角度看,LP64模型意味着我们

《UNIX网络编程 卷1:套接字联网API(第3版)》——1.3 协议无关性

1.3 协议无关性 图1-5中的程序是与IPv4协议相关的:我们分配并初始化一个sockaddr_in类型的结构,把该结构的协议族成员设置为AF_INET,并指定socket函数的第一个参数为AF_INET. 为了让图1-5中的程序能够在IPv6上运行,我们必须修改这段代码.图1-6所示的是一个能够在IPv6上运行的版本,其中改动之处用加粗的等宽字体突出显示. 我们只修改了程序的5行代码,得到的却是另一个与协议相关的程序:这回是与IPv6协议相关的.更好的做法是编写协议无关的程序.图11-11将