【OSI】传输控制层 – TCP 协议

TCP

为了搞清楚TCP是什么,先来看一下它的定义:

传输 控制协议(英语:Transmission Control Protocol,缩写:TCP)是一种面向连接的、可靠的、基于字节流传输层通信协议。

image

注: 上图中的 connect()、listen()、write()、read()、close() 均是系统调用方法。

TCP三次握手

TCP 建立三次握手的过程如下图:

image

  1. Client 给 Server 发送一个 syn 包
  2. Server 给 Client 响应一个 syn+ack 包
  3. Client 再给 Server 发送一个 ack 包

如果只有两次的话,Server 只能确认你请发送请求的通道是通的,不能确认 Server 响应给 Client 是否是通的。

这个过程发生在 传输控制层,同步序列号后就会各自建立资源,这个资源就是连接。

socket

image

上面建立的资源就是 socket, socket 就是四元组, 是唯一的。

一个 server 可以接收很多 client 的连接,server 在响应的时候如何正确的将数据响应给之前请求的 client,而不会响应给其他 client。

数据包如何在复杂的共享通信介质的网络当中正确的通信?

不管是 client 还是 server,只要看到一个socket(ip+port:ip+port), 就可以正确的通信双方可以找到对方。

  • 一台机器的 port 取值范围是?

    • 0-65535,两个字节;
  • 已知 server 通过 nginx 监听 80 端口, 那么client 可以和 server 最多建立多少个连接?

    • 理论上可以最多可以建立 65535 个,client 每次建立连接都会随机申请一个端口号。65535 个连接其实就是 65535 个socket。(client再加一个网卡,那么再多了一个 IP 也就可以再多建立 65535 个连接)
  • server 消耗多少个端口号?

    • 一个 80 端口

可以通过下面命令查看IP及端口还有TCP状态的变更:

$ netstat -natp

TCP 四次挥手

image

对于4次挥手,其实你仔细看是2次,因为TCP是全双工的,所以,发送方和接收方都需要 FINACK

只不过,有一方是被动的,所以看上去就成了所谓的4次挥手。如果两边同时断连接,那就会就进入到CLOSING状态,然后到达TIME_WAIT状态。下图是双方同时断连接的示意图:

image

关于 MSL 和 TIME_WAIT

我们注意到,在TCP的状态图中,主动断开连接的一方,从TIME_WAIT状态到CLOSED状态,有一个超时设置,这个超时设置是 2*MSL(RFC793定义了MSL为2分钟,Linux设置成了30s)

为什么要这有TIME_WAIT?为什么不直接给转成CLOSED状态呢?

主要有两个原因:

  • TIME_WAIT确保有足够的时间让对端收到了ACK,如果被动关闭的那方没有收到Ack,就会触发被动端重发Fin,一来一去正好2个MSL,

  • 有足够的时间让这个连接不会跟后面的连接混在一起

    • 你要知道,有些自做主张的路由器会缓存IP数据包,如果连接被重用了,那么这些延迟收到的包就有可能会跟新连接混在一起。
    • client 在连接已经关闭之前发了一个消息,然后延迟到达重新复用了这个端口建立新的连接,那么就会对接收方造成数据错乱的影响。TIME-WAIT 保障了延迟到达的数据不会扰乱新连接。

tcpdump

tcpdump 之前先来看下,TCP 连接中五个常见 flag 标志位

TCP 连接常见 flag 标志位

  • SYN表示建立连接;
  • FIN表示关闭连接;
  • ACK表示响应;
  • PSH表示有 DATA数据传输;
  • RST表示连接重置

在 tcpdump 中的的表示:

  • F : FIN - 结束; 结束会话
  • S : SYN - 同步; 表示开始会话请求
  • R : RST - 复位;中断一个连接
  • P : PUSH - 推送; 数据包立即发送,不要放入缓冲区,放入缓冲区就会延时
  • . : 没有 Flag (意思是除上面四种类型外的其他情况,有可能是 ACK 也有可能是 URG)

tcpdump 实例

连接百度:

$ curl www.baidu.com
$ tcpdump -nn -i eth0 port 80 or arp

image

小结

  1. 应用程序想建立连接,就得 new 一个 socket,调用内核,内核先准备了握手的第一个包。

  2. 传输控制层 创建好第一个 syn 包(开始阻塞),然后交给 网络层,网络层来决定这个包从哪个网卡哪个接口出去,

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇