我正在学习C语言中的网络编程,并且有一个问题困扰我很多,目标端口在TCP三向握手期间会发生变化吗?假设我有一个在端口5000上运行的cilent应用程序,在tcp端口80上运行的Web服务器。端口(假设为5000)
所以我的理解是,客户端的初始地址用于将数据包发送到服务器的ip地址+端口80,然后在服务器(侦听端口80)接受请求并创建后一个新的连接端口(5000),然后客户端发送到Web服务器的后续数据包(包含数据有效负载)是服务器的IP地址+端口5000。因此,如果使用Wireshark捕获数据包,则目标端口实际上从80更改为5000您将在TCP标头中看到两个端口80和5000作为目标端口,我的理解正确吗?

评论

您的Web服务器是否充当其他服务的反向代理(例如,例如node.js)?在这种情况下,它们是两个独立的TCP套接字,其中一个用于将远程用户与端口80上运行的HTTP服务器进行通信,而另一个则将HTTP服务器与端口5000上运行的后端(node.js等)服务器之间进行通信。

@secondimage与HTTP或HTTPS服务器一起使用时,服务器端端口始终相同(默认为80或443)。另一个端口没有更改,例如您的示例中的端口5000。 FTP在端口21上使用控制流,而在随机高端口上使用数据流,但HTTP不使用,它停留在一个端口上。

由于答案中的原因,只有一种可以按照您描述的方式工作的协议,即通过UDP的TFTP,但没有基于TCP的协议。

再次仔细阅读问题,我认为您会混淆从客户端到HTTP服务器再返回的数据包。您可以共享一个wireshark走线吗?双向IP /端口是否相同?

虽然不是严格地解决问题的方法,但是在打开与服务器的Web连接时安装Wireshark并运行它可以为您捕获会话。然后,您可以查看事实之后,逐个分组地进行研究。这对于了解正在发生的事情非常有帮助。

#1 楼

不,TCP连接由源IP和目标IP以及TCP(端口)地址唯一标识。更改其中任何一个都将断开TCP连接(或防止其在握手中形成)。
您可能要指的是Web浏览器将通过与之建立,使用并关闭多个TCP连接这一事实。网络服务器。每个连接将使用不同的浏览器TCP源端口。

根据您的注释进行编辑:
RFC 793,传输控制协议定义了TCP,它解释了:

多路复用:
为了允许单个主机中的多个进程同时使用TCP
通信工具,TCP在每个主机中提供了一组
地址或端口。与Internet通信层中的网络和主机地址连接在一起,形成一个套接字。一对插座唯一地标识每个连接。就是说,一个套接字可以同时用于多个连接。
端口到进程的绑定是由每个主机单独处理的。但是,将常用的进程
(例如“记录器”或分时服务)附加到已为公众所知的固定套接字上被证明是有用的。然后可以通过
已知地址访问这些服务。建立和学习其他进程的端口地址可能涉及更多的动态机制。
连接:
上述可靠性和流控制机制要求TCP初始化并维护某些状态信息对于每个
数据流。此信息的组合(包括套接字,
序列号和窗口大小)被称为连接。每个
连接由一对套接字唯一标识,该套接字标识其
两侧。
当两个进程希望进行通信时,它们的TCP必须首先
建立连接(初始化状态信息在每个
上侧)。它们的通信完成后,该连接将被终止或关闭以释放资源以供其他用途。由于必须在不可靠的主机之间建立连接,并且
必须通过不可靠的Internet通信系统建立连接,因此握手
基于时钟的序列号机制可避免错误的连接初始化。

TCP在进程/应用程序对等之间创建双向连接(就像以太网创建双向连接一样)主机之间),并且双方均可使用该连接进行发送和接收。 TCP本身没有客户端或服务器,这是应用程序层的概念。 Web浏览器将使用TCP连接将请求发送到Web服务器,Web服务器将使用相同的连接将对请求的响应发送回Web浏览器。
Web浏览器可以发送多个请求并接收对同一TCP连接上的请求的答复。某些Web浏览器将建立与Web服务器的多个连接,以便同时请求不同的Web网页元素,但这是应用程序层的行为,而不是TCP的行为,并且此处的应用程序行为不在主题之列。 br />服务器进程通常侦听一个众所周知的端口号,例如HTTP的TCP端口80。客户端进程将请求TCP在服务器的已知端口号上创建到服务器进程的连接,并且通常使用保留端口0,以便TCP将为该连接分配客户端进程的临时端口号。当TCP连接终止时(任一端都可以终止连接),临时端口将返回临时端口号池,以重新用于其他连接。一些操作系统将以特定顺序使用可用池中的临时端口号,而某些操作系统将为每个连接随机选择一个临时端口号。
RFC:

2.7中说明了连接的实际建立。连接建立和清除
为了标识TCP可以处理的单独数据流,TCP
提供了端口标识符。由于端口标识符是由每个TCP独立选择的,因此它们可能不是唯一的。为了在每个TCP中提供唯一的地址,我们将Internet地址连接起来,以将TCP与端口标识符进行标识,以创建一个套接字,该套接字在连接在一起的所有网络中都是唯一的。 >连接由两端的一对插座完全指定。
本地套接字可能会参与到不同的外国
套接字的许多连接。连接可以用于双向传输数据,即“全双工”。
TCP可以随意选择将端口与进程关联起来。
但是,基本在任何实现中,概念都是必不可少的。
必须有一些众所周知的套接字,TCP只能通过某种方式与“适当的”进程关联。我们设想进程
可能“拥有”端口,并且进程只能在它们拥有的端口上启动连接。 (实现所有权的方法是本地问题,但我们设想了“请求端口”用户命令,或
将端口组唯一分配给给定进程的方法,例如,通过
关联
通过本地端口和
外部套接字参数在OPEN调用中指定连接。作为回报,TCP提供一个(简短的)本地
连接名称,用户通过该名称在随后的调用中引用该连接。关于连接,必须记住几件事。为了存储此信息,我们假设存在一个称为传输控制块(TCB)的数据结构。一个
实施策略的本地连接名称为
指向此连接的TCB的指针。 OPEN调用还指定
是要主动进行连接建立还是要被动地等待。
被动OPEN请求意味着该进程要接受传入的信息
连接请求而不是尝试启动连接。
请求被动OPEN的过程通常会接受来自任何调用方的连接
请求。在这种情况下,全零的外部套接字用于表示未指定的套接字。未指定的外部套接字仅在被动OPEN上被允许。
希望为未知的其他进程提供服务的服务进程将使用未指定的外部套接字发出被动OPEN请求。然后可以使用任何请求到此本地套接字的连接的进程进行连接。如果已知此
本地套接字与此服务相关联。
众所周知的套接字是一种将套接字地址与标准服务进行先验关联的便捷机制。例如,
“ Telnet-Server”进程已永久分配给特定的
套接字,而其他套接字保留用于文件传输,远程作业
条目,文本生成器,Echoer和接收器流程(最后三个
用于测试)。套接字地址可能被保留用于
访问“查找”服务,该服务将返回特定的套接字
,在该套接字上将提供新创建的服务。
套接字的概念是TCP规范的一部分,但是服务的套接字
分配不在此规范之内。 (请参见[4]。)
进程可以发出被动OPEN,并等待其他进程匹配主动OPEN
,并在建立连接后由TCP通知。可以同时连接两个同时向彼此发出活动OPEN的两个进程。这种灵活性
对于分布式计算的支持至关重要,在分布式计算中,各个组件之间相互异步操作。
有两种主要情况可以匹配本地
被动OPEN和外部主动OPEN中的套接字。在第一种情况下,
本地无源OPEN已完全指定了外部套接字。在这种情况下,匹配必须准确。在第二种情况下,本地无源
OPENs未指定外部套接字。在这种情况下,只要本地套接字匹配,任何
外部套接字都是可接受的。其他
可能性包括部分受限制的匹配。
如果有多个具有相同本地套接字的未决被动OPEN(记录在TCB中),则外部主动OPEN将与TCB匹配
使用外部活动OPEN中的特定外部套接字,如果存在这样的
TCB,则在选择具有未指定外部套接字的TCB之前。
建立连接的过程利用同步(SYN)
control标志,并涉及三个消息的交换。这种交换被称为三向握手[3]。
连接由到达段的集合发起,该段包含一个SYN和一个等待的TCB条目,每个条目由一个SYN和一个用户OPEN
命令。本地和外部套接字的匹配确定何时启动
连接。当两个方向上的序列号同步时,连接将“建立”。
连接的清除还涉及交换段,在这种情况下,该段带有FIN控制标志。
br />

评论


不,只有一个连接。连接由四个不同的符号标识。请参阅RFC 793,传输控制协议:“为了允许单个主机内的多个进程同时使用TCP通信工具,TCP在每个主机内提供一组地址或端口。与来自Internet通信层的网络和主机地址连接在一起,这形成一个套接字。一对套接字唯一地标识每个连接。”

–罗恩·莫潘♦
20 Dec 24'2:59

@secondimage绝对不是它的工作方式。客户端从OS请求并分配一个临时端口(某种程度上是随机的),并使用它来连接到服务器-故事的结尾。

– Zac67
20 Dec 24 '10:39

@secondimage否。HTTP请求和响应使用完全相同的套接字(=无需更改端口),甚至对多个请求和后续响应也进行流水线操作。您可能需要重新阅读RFC7230。显然,您正在将TCP与BSD样式套接字的API处理混在一起。

– Zac67
20 Dec 24'11:44



@secondimage您的困惑是客户在“在端口1234上运行”。通常,只有服务器具有固定端口。客户端为其建立的每个连接获取一个不同的本地端口。

– Barmar
20/12/24在16:11

@secondimage我认为,造成混乱的部分原因是在服务器端,有一个套接字对象用于侦听客户端连接,并且当客户端连接时,会创建另一个套接字以与该客户端进行通信。但是,两个套接字共享相同的服务器端端口号。

–大卫
20 Dec 25'4:58

#2 楼


我们知道端口80只是一个受欢迎的端口,当Web服务器收到一个http请求时,它会创建一个新的连接端口(比如说5000)。

对于HTTP协议来说是不正确的。某些协议(即FTP)的工作原理与此类似,但HTTP却没有。

所以我的理解是,客户端的初始地址用于将数据包发送到服务器的ip地址+端口80,之后服务器(侦听端口80)接受请求并创建一个新的连接端口(5000),然后客户端发送到Web服务器的后续数据包(包含数据有效负载)是服务器的IP地址+端口5000

不适用于HTTP(如您所说的“ Web服务器”)
对于HTTP,流量看起来像:

客户端选择一个临时端口。例如,假设选择了12345
,客户端发送一个设置了SYN标志的数据包,该数据包的源端口为12345,目标IP为服务器地址,目标端口为80
server接收到该数据包,并发送带有第一个数据包的源IP和端口(目标端口12345)的目的地设置的SYN,ACK标志的数据包,并且源端口80
客户端接收到该数据包,并发送回带有ACK标志设置的数据包(再次源端口12345和目标端口80)
连接现已打开。客户端发送带有HTTP请求(GET / HTTP/1.1...或类似的请求)的数据包(源端口12345,目的端口80)
服务器以相同的方式处理请求并发送回响应(源端口80,目的端口12345) )

因为这是HTTP,所以很可能正在传输HTML,这将触发其他HTTP请求以获取资产(图像,CSS,javascript等)。除了临时端口(12345)会有所不同之外,这些其他HTTP请求与上述请求完全相同,但服务器的源端口始终为80。

现在,如果您要询问使用两个端口(即FTP)的不同协议,则通信流程将类似于:

客户端选择一个临时端口。例如,假设选择了12345
,客户端发送设置了SYN标志的数据包,该数据包的源端口为12345,目标IP为服务器地址,目标端口21为
server接收到该数据包,并发送带有第一个数据包的源IP和端口(目标端口12345)的目的地的SYN,ACK标志设置的数据包,并且源端口21
客户端接收到该数据包,并发送回带有ACK标志设置的数据包(再次源端口12345和目标端口21)
控制连接现已打开。客户端发送带有FTP请求的数据包(源端口12345,目标端口21)。
当需要传输数据时,服务器(或客户端,取决于PASV模式...)选择-second_该通道的端口,第二个三向握手发生在该端口上。 (从sport 23456到qst120端口的SYN,从dport 23456到SYNACK的端口,到q5000的ACK的端口)
现在,您有两个TCP连接;一个用于命令(“发送该文件的数据,停止,更改目录...”),第二个用于实际的数据流

,但是即使在这种情况下,目标端口在此期间也不会更改TCP三向握手-有两个单独的三向握手。

评论


好吧-欢迎来到NESE!

– Zac67
20/12/24在16:34

“这些其他HTTP请求看起来与上面的请求完全相同,不同之处在于临时端口(12345)有所不同,但服务器的源端口始终为80。”通常,如果后续请求从同一服务器请求资源,它们将仅使用同一连接。如果请求不包含Connection:close标头,则这是HTTP 1.1的标准行为。不过,您所描述的是HTTP 1.0的正常行为。

– reirab
20 Dec 24 '17:36



@reirab,尤其是HTTP / 2。使用HTTP / 1.1,客户端通常会建立多达4个(不同,但这是5-10年前的默认默认设置)同时持久性HTTP连接,以同时下载图像和其他资产。我能想到的与OP关于“它创建一个新的连接端口”的描述接近的唯一事情是用于同时下载的多个HTTP连接。

–乔什
20 Dec 24 '17:49

#3 楼


我们知道端口80只是一个欢迎端口,当Web服务器收到一个http请求时,它会创建一个新的连接端口(假设为5000)。

这似乎是你的误会这是不准确的。进行连接时,客户端会选择一个随机的高编号端口作为源端口。这是在发送TCP SYN数据包之前发生的,因此在握手期间它不会更改。在TCP连接的整个生命周期中,目标端口始终是端口80。目的端口唯一不同的是,如果您在同一主机上使用相同的IP地址运行多个Web服务器,在这种情况下,与主机上每个单个Web服务器的所有连接仍将连接到一个端口,但不同的服务器将在不同的端口号上运行。
TCP连接由4个值唯一标识:源IP地址,目标IP地址,源端口号和目标端口号。不需要每个客户端的目标端口号都不同,因为源IP地址和端口号将唯一标识每个客户端的连接,因此服务器的操作系统知道将哪个数据包传递到Web中的哪个TCP套接字。服务器(或任何类型的服务器。)
只要每个客户端具有唯一的源IP地址和端口地址组合,则给定的主机就可以支持尽可能多的客户端同时连接到同一TCP端口。 >

#4 楼

不,!服务器目标端口永远不会更改,在您的方案中它始终是http端口80。应用程序托管在端口80上,服务正在目标服务器上的端口80上侦听。
当客户端请求访问端口80上的Web服务器时,客户端将生成一个源端口(根据您的示例)它是端口5000,目标端口是端口80和端口5000用作反向到正常流量的参考,以纠正从中产生流量的主机。

评论


我认为您误会了它,如果您进行了Web服务器编程,则在服务器端而不是客户端端会生成连接端口5000。正是此端口将成为cilentas目标端口

–secondimage
20 Dec 24'在5:29

@secondimage:这实际上是正确的答案。客户端启动到服务器上端口80的连接,并选择一个“临时端口”。服务器未选择它。

–jornane
20/12/24在16:59

@secondimage许多人都在努力告诉您您是被误解了的人,但是您没有听我们的声音。您说您已经编写了代码-也许您应该向我们展示代码?

– Glenn Willen
20 Dec 25'2:47

@Glenn Willeb为我的错误感到抱歉,我混淆了端口和文件描述符

–secondimage
20/12/26在4:26

#5 楼


我们知道端口80只是一个欢迎端口,当Web服务器收到一个http请求时,它会创建一个新的连接端口(比如说5000)。

不,那不是真的。端口80是所有发送到Web服务器的Web服务的数据包都发送到的目标端口。

所以我的理解是,客户端的初始地址用于将数据包发送到服务器的ip地址+端口80,并且服务器(侦听端口80)接受请求并创建新的连接端口(5000)之后,客户端发送到Web服务器的后续数据包(包含数据有效负载)就是服务器的IP地址+端口5000。 br />
Web服务器现在具有新的连接。我不知道我会说网络服务器创建了它。我会说客户创建了它。无论如何,Web服务器无法选择任何有关连接的信息,因为已经选择了所有连接。
从Web服务器的角度来看,其本地IP地址就是客户端向其发送数据包的IP地址。它的本地端口是80。远程IP地址是客户端从其发送数据包的任何IP地址。远程端口是客户端从其发送数据包的端口。
Web服务器没有任何选择。

因此,如果使用,目标端口实际上从80更改为5000。 Wireshark捕获数据包您将在TCP标头中看到两个端口80和5000作为目标端口,我的理解正确吗?

哪个端口是“目标”端口取决于数据包的前进方向。对于发送到Web服务器的数据包,目标端口是80。对于来自Web服务器的数据包,目标端口是客户端从其发送数据包的任何端口。客户端在将第一个数据包发送到Web服务器时选择了它。
每个TCP数据包都有一个源端口,源IP地址,目标端口和目标IP地址。对于在一个方向上传输的数据包,与另一方向相比,源和目标被翻转。
客户端首先发送创建连接的第一个数据包。因此客户选择了已经选择的所有四个参数。当然,该数据包必须具有80的目标端口,否则Web服务器进程将无法获取它。当然,该数据包必须具有Web服务器正在侦听且已分配给它的目标IP地址。