0

出于好奇,在建立与端口的连接(使用 Java 套接字)时实际发送了多少数据。它是 Socket 对象的大小吗?套接字连接对象?

4

2 回答 2

4

您对 TCP 网络连接的理解似乎将它们与电路混为一谈。(可以理解,鉴于你的背景。)

从物理的角度来看,没有连接之类的东西,只有数据包。通过 TCP 协议,两台设备同意建立逻辑(即软件)连接。客户端首先向远程主机发送数据(SYN),服务器将数据返回给客户端(SYN-ACK),客户端发送最终确认(ACK)来建立连接。 所有这些协商必然会消耗带宽,并且当您终止连接时,您必须协商一个全新的连接以再次开始发送数据。

例如,我将从我的机器连接到本地 Web 服务器 192.168.1.2:80。

首先,我的机器发送一个 TCP SYN。这将通过线路发送 66 个字节:(标头用 分隔|

0000  00 24 8c a9 4c b4 00 1e  68 66 20 79 08 00|45 00   .$..L... hf y..E.
0010  00 34 53 98 40 00 80 06  00 00 c0 a8 01 0b c0 a8   .4S.@... ........
0020  01 02|36 0a 00 50 09 ef  3a a7 00 00 00 00 80 02   ..6..P.. :.......
0030  20 00 50 c8 00 00 02 04  05 b4 01 03 03 02 01 01    .P..... ........
0040  04 02                                              ..               

前 14 个字节是以太网帧,指定此数据包的目标 MAC 地址。这通常是上游路由器,但在这种情况下,服务器恰好在同一个交换机上,所以它是机器的MAC地址,00:24:8c:a9:4c:b4。接下来是源(我的)MAC,以及有效负载类型(IP,0x0800)。接下来的 20 个字节是 IPv4 标头,然后是 32 个字节的 TCP 标头。

服务器以 62 字节的 SYN-ACK 响应:

0000  00 1e 68 66 20 79 00 24  8c a9 4c b4 08 00|45 00   ..hf y.$ ..L...E.
0010  00 30 69 b9 40 00 80 06  0d b1 c0 a8 01 02 c0 a8   .0i.@... ........
0020  01 0b|00 50 36 0a d3 ae  9a 73 09 ef 3a a8 70 12   ...P6... .s..:.p.
0030  20 00 f6 9d 00 00 02 04  05 b4 01 01 04 02          ....... ......  

同样,14 字节的以太网报头、20 字节的 IP 报头和 28 字节的 TCP 报头。我发送一个 ACK​​:

0000  00 24 8c a9 4c b4 00 1e  68 66 20 79 08 00|45 00   .$..L... hf y..E.
0010  00 28 53 9a 40 00 80 06  00 00 c0 a8 01 0b c0 a8   .(S.@... ........
0020  01 02|36 0a 00 50 09 ef  3a a8 d3 ae 9a 74 50 10   ..6..P.. :....tP.
0030  fa f0 83 78 00 00                                  ...x..           

14 + 20 + 20 = 54 字节通过线路(顺便说一下,这是 TCP 数据包可能的最小大小——SYN 和 SYN-ACK 数据包更大,因为它们包含选项)。

这通过线路增加了多达182个字节来建立连接;现在我可以开始向服务器发送实际数据了:

0000  00 24 8c a9 4c b4 00 1e  68 66 20 79 08 00 45|00   .$..L... hf y..E.
0010  01 9d 53 9d 40 00 80 06  00 00 c0 a8 01 0b c0 a8   ..S.@... ........
0020  01 02|36 0a 00 50 09 ef  3a a8 d3 ae 9a 74 50 18   ..6..P.. :....tP.
0030  fa f0 84 ed 00 00|47 45  54 20 2f 20 48 54 54 50   ......GE T / HTTP
0040  2f 31 2e 31 0d 0a 48 6f  73 74 3a 20 66 73 0d 0a   /1.1..Ho st: fs..
...

14 以太网 + 20 IP + 20 TCP + 数据,在本例中为 HTTP。


所以我们可以看到,建立一个 TCP 连接需要大约 182 个字节,而终止一个 TCP 连接需要额外的 162-216 个字节(取决于是 4-way FIN ACK FIN ACK 还是更常见的 3-way FIN FIN-ACK使用 ACK 终止握手),通过断开和重新连接添加近 400 个字节来“脉冲”连接。

与通过已建立的连接发送一个字节数据的 55 个字节相比,这显然是一种浪费。

What you want to do is establish one connection and then send data as-needed. If you're really bandwidth constrained, you could use UDP (which requires no handshaking at all and has an overhead of only 14 Ethernet + 20 IP + 8 UDP bytes per packet), but then you face the problem of using an unreliable transport, and having to handle lost packets on your own.

于 2012-06-03T23:55:42.693 回答
1

TCP 数据包的最小大小为 40 字节。创建一个连接需要三个交换的数据包,两个来自客户端,一个来自服务器,另外四个来关闭它,每个方向两个。连接交换中的最后一个数据包也可以包含数据,每个方向的关闭交换中的第一个数据包也可以包含数据,这可以稍微摊销它,正如下面@josh3736 的评论所结合的传出 FIN 和 ACK 一样。

于 2012-06-03T22:49:23.600 回答