(我对 TCP 握手以及如何分配端口号有疑问,如果这不属于此处,请告诉我。)
你好,我正在通过 Douglas Comer 的《Internetworking with TCP/IP》一书学习 TCP/IP。在 TCP 章节中,提到 TCP 将“端点”定义为一对(IP 地址、端口号),而连接由两个端点定义。
这有几个含义,例如,本地 TCP 端口可以同时进行多个连接,只要不存在来自同一 IP 和同一偏僻的端口。这也意味着建立的连接数量几乎是无限的(每个 IPv4 地址有 2^16 个连接,总共有 2^48 个连接)。
现在,在课堂上,我被告知,当一个人连接到一个监听端口时,双方同意使用不同的端口,这样通信就可以进行,而监听套接字仍然空闲。这也是我在读这本书之前所相信的。
现在我觉得我显然应该相信这本书(《It's Comer!》),但另一种解释有道理吗?
谢谢
答案1
不,另一种说法不成立。您可能误以为这是主动 FTP。
答案2
首先,基础知识 - 套接字是 (srcip、srcport、dstip、dstport) 的 4 元组。如果这些值中的任何一个发生变化,它就是不同的套接字。当给定主机打开 TCP(或 UDP)套接字时,其源 IP 是已知的,源端口是从临时范围(大于 1023 或 1024 - 忘记哪个)中随机选择的,并且目标 IP 和端口由调用进程提供给堆栈。
在服务器端,建立连接并查看来自给定的 srcip 和 srcport 并绑定到 dstport 和 dstip 的连接。此条目(再次 - 一些 4 元组)保存在主机的连接表中,然后允许传入数据包与适当的连接相关联。
TCP 握手是双方 TCP 堆栈协商序列号、窗口大小等参数的过程。当发生此过程时,端口号已经确定。
再次 - 如果任何如果这些元组中的值在初始连接之后发生变化,那么根据定义,数据包不再与原始套接字相关联。
在某些情况下,正在使用的应用程序(例如 FTP、RPC)可能会指定其他端口号,但在所有情况下,这都需要建立分离套接字,而不是对现有套接字进行重新编号。在 FTP 情况下,这将对应于从主机 -> 服务器在端口 21(控制)上的初始连接,然后是端口 20(数据)上的后续连接 - 根据使用的模式,可以在任一方向上设置。不过,我再怎么强调也不为过,这构成了两个独立的套接字。回顾 OSI 堆栈,这很可能是一个第 5 层问题。
答案3
本地 TCP 端口可以同时进行多个连接
是的 - 为了让客户寻找一项服务,那么它总是在服务器上的特定端口上运行 - HTTP 为 80,SMTP 为 25,ssh 为 22... Web 服务器将有许多客户端连接到其端口 80。
在课堂上,我被告知,当一个人连接到一个监听端口时,双方同意使用不同的端口
要么是你,要么是你的老师不明白发生了什么。有些协议中,客户端和服务器将协商不同的套接字 - FTP 数据连接、某些形式的 rpc 和(如果我没记错的话)Oracle 的 sql*net 的早期版本就是这样工作的 - 但非常罕见。
你的老师是受雇来了解问题并回答你的问题的人——我建议你回到他/她那里。
答案4
这对于 Server Fault 来说绝对是一个题外话,但是你有一个可怕的误解需要纠正:-)
首先,你可能想扔掉他们正在读的科默书,然后拿起一本TCP/IP 图解(史蒂文斯)——这很大程度上是个人喜好,但我认识的每个人都更喜欢史蒂文斯的书。
现在来谈谈你的问题:
TCP 将“端点”定义为一对(IP 地址、端口号),而一个连接由两个端点定义。
从概念上来说,这是正确的。确实发生协议层上的连接略有不同,但 TCP 连接的概念是客户端(例如您的 Web 浏览器)打开本地套接字(10.0.0.1 端口 30000)并连接到服务器(10.10.10.10 端口 80)。
连接是这两个端点之间的通道。
现在,在课堂上,我被告知,当一个人连接到一个监听端口时,双方都同意使用不同的端口,这样就可以进行通信,并且监听套接字保持空闲。
这是半正确的——听起来你试图描述的是rendezvous socket
服务器上监听行为的混乱版本。
正如你所猜测的,如果我们只是通过会合套接字进行通信,那么一次只有一台机器可以连接到给定的监听器(这有点没用),所以实际发生的是当服务器accept()
建立连接时,服务器端的 TCP 堆栈会交出一个新的连接套接字,实际对话就发生在这个套接字上。
有关所有细节,请参阅 Stevens 的书,其中有更简短的描述尝试这个 StackOverflow 问题。
如果你想了解一点历史知识,这个视频可能会让你感兴趣(此链接中书签的时间大约是开始讨论 TCP 的时间,但整个视频或 3 部分系列是任何正在学习操作系统设计和/或网络的计算机科学专业认真学生都应该观看的)。