
yuyi
MTU(Maximum Transmission Unit):MTU 是网络链路层(通常是数据链路层)的一个概念,表示在特定网络链路上能够传输的最大数据包的大小。MSS 的计算通常基于 MTU 的值。
IP 头部大小:MSS 的计算还可能考虑 IP 头部的大小,因为 IP 头部也会占用数据包的一部分。
TCP 头部大小:TCP 头部包含了一些控制信息,也会占用数据包的一部分。
通常情况下,MSS 的计算不需要涉及 MAC 地址,因为 MAC 地址是用于局域网内设备之间的通信,而 MSS 主要用于 TCP 层的控制。计算 MSS 主要涉及确定 TCP 数据包的最大大小,以便它们可以正确地在网络链路上传输,而不会导致分段或丢失数据。MAC 地址在更低的数据链路层中使用,用于设备之间的帧传输。
IP 头部和TCP 头部通常都大致是20字节的主要原因是设计和历史因素以及网络协议的需要。让我们分别看看这两个头部的原因:
地址信息:IP 头部包含源IP地址和目标IP地址,每个地址通常占4字节,共8字节。
服务质量(Quality of Service):用于指定数据包的优先级和服务质量的字段。
生存时间(Time to Live):指示数据包在网络中的最大生存时间,以防止数据包在网络中永远循环。
协议字段:指示上层协议,例如TCP、UDP或ICMP。
头部校验和:用于校验IP头部的完整性。
其他标志和字段:还包括一些其他字段,如标识、标志位和片偏移等。
综合以上信息,IPv4 头部通常占用20字节。
总的来说,这些状态描述了TCP连接在建立、使用和关闭过程中的不同阶段。每个状态都有特定的行为和条件。需要注意的是,具体的实现和细节可能会因TCP栈的不同而略有不同,但上述描述是一种通用的表达方式。
当你在Wireshark中捕获数据时,你会遇到多个网络接口。例如:WI-FI:en0
和 Loopback:lo0
。选择哪个取决于你想捕获哪种类型的流量:
WI-FI:en0:
Loopback:lo0:
在Wireshark中使用过滤器捕获C++ TCP程序的流量,首先你需要知道一些关于你的程序的基本信息,如使用的端口号或与之通信的IP地址。以下是如何设置不同的过滤器:
基于端口过滤:
如果你知道你的C++ TCP程序使用的确切端口号,你可以设置一个简单的过滤器。
tcp.port == 12345
这里,12345
是你程序使用的端口号。替换为实际的端口号。
基于源或目的IP地址过滤:
如果你知道与你的程序通信的特定IP地址,可以使用以下过滤器:
ip.src == 192.168.1.100 || ip.dst == 192.168.1.100
其中192.168.1.100
是你要过滤的IP地址。这将显示所有从或到该IP地址的数据包。
组合端口和IP地址过滤:
tcp.port == 12345 && (ip.src == 192.168.1.100 || ip.dst == 192.168.1.100)
仅显示SYN包:
如果你只想看到TCP连接的建立(SYN包),你可以使用以下过滤器:
tcp.flags.syn == 1 && tcp.flags.ack == 0
跟踪特定的TCP流:
Follow
> TCP Stream
。这将过滤并只显示该特定TCP连接的所有数据包。一旦你输入了过滤器,按Enter
键。Wireshark将立即应用这个过滤器并只显示匹配的数据包。
为了更准确地捕获你的C++程序的流量,最好先知道它使用的端口或与其通信的其他相关信息。如果你的程序动态地选择端口,那么你可能需要先捕获所有流量,然后根据其他标识信息(如协议内容或特定的数据包模式)来找到你的程序的流量。
你提供的这条记录是TCP三次握手的第一步。根据你给出的信息,我们可以分析以下内容:
43 22.189229 127.0.0.1 127.0.0.1 TCP 68 50801 → 20749 [SYN] Seq=0 Win=65535 Len=0 MSS=16344 WS=64 TSval=2710313451 TSecr=0 SACK_PERM
43
: 数据包编号。22.189229
: 时间戳,表示此数据包被捕获的时间。127.0.0.1
: 源IP地址。这是一个loopback地址,表示这是在本地机器上生成的数据包。127.0.0.1
: 目的IP地址。也是一个loopback地址,表示这个数据包是发送给本地机器的。TCP
: 表示这是一个TCP协议的数据包。68
: 数据包的总长度(包括头部和数据)。50801 → 20749
: 源端口号50801到目标端口号20749的通信。[SYN]
: 这是一个SYN包,表示尝试建立一个新的TCP连接。Seq=0
: 序列号是0,这是一个新连接的开始。Win=65535
: 窗口大小。这告诉接收方发送方的缓冲区有多少空间可以接收数据。Len=0
: 数据长度是0,因为这只是一个SYN包,没有携带任何实际的数据。MSS=16344
: 最大分段大小。这是发送方告诉接收方它愿意接收的每个TCP段的最大长度。WS=64
: 窗口扩大因子。TSval=2710313451
: 时间戳值。TSecr=0
: 时间戳回应值,因为这是SYN包,所以它的值为0。SACK_PERM
: 表示发送方支持选择性确认(Selective Acknowledgment)。要完全了解TCP三次握手的过程,你应该寻找以下三个主要数据包:
在你给出的这个例子中,你已经有了第一步(SYN)。为了完全理解这个TCP握手,你需要找到与之匹配的SYN-ACK和ACK数据包。你可以在Wireshark中继续查看接下来的数据包,寻找来自目的端口20749的回应。
客户端使用 int connect(int, const struct sockaddr *, socklen_t)
命令连接服务器时,三次握手建立连接。
客户端与服务器之间连接断开时,四次挥手。
Wireshark 抓包结果中显示的 TCP 最大报文段大小(Maximum Segment Size, MSS)是在 TCP 三次握手过程的同步(SYN)报文中协商的。MSS 指的是 TCP 报文段中可承载的最大数据量,不包括 TCP 头部和IP头部的大小。正常情况下,MSS 的大小是根据MTU(Maximum Transmission Unit)来决定的,以避免IP层发生分片。
在大多数以太网中,MTU 的大小是 1500 字节,如果去掉 IP 头(通常20字节)和 TCP 头(通常20字节),标准的 MSS 大小通常是 1460 字节。然而,某些特殊的网络环境或配置可能使用不同的 MTU 值。
具体到您提到的 16344 字节的 MSS,这是一个非常大的值,可能反映了以下情况:
当 Wireshark 显示这样的数值时,它是基于实际捕获的网络流量来显示这些值的。如果在一个标准的互联网环境中看到这样的值,需要考虑是否有某些网络设备或软件错误地报告了这个值。在大多数互联网传输场景中,遇到如此大的 MSS 值是不常见的,可能需要进一步的技术分析来确定原因。
在本地 loopback 接口上抓取到的数据通常反映的是本地机器内部虚拟网络的配置。由于 loopback 流量不会通过任何物理网络设备,所以它不受到常见的以太网MTU限制(如1500字节)。这意味着操作系统可以使用更大的MSS值,因为它知道这些TCP段不需要在物理媒体上被传输,也就不会遇到需要分片的问题。
在本地通信中,TCP可以设置更大的MSS,因为:
因此,如果您在本地loopback地址上看到16344字节的MSS值,这可能是您的操作系统或应用程序在本地环境中为了效率而设置的。它并不代表实际通过物理网络传输的数据包会使用这样的MSS值,因为实际的网络传输还必须考虑到其他许多因素,如不同网络段的MTU限制。
〉Issues-1: 什么是区域传送? 为什么区域传送要用 TCP?
〉Issues-2: 什么是 TCP 粘包? TCP 粘包问题的复现与解决?
〉Issues-3: TCP 头部报文字段包含哪些内容?