<commit_before>---
layout: post
title: "TCP三次握手和四次挥手"
description: "TCP三次握手和四次挥手"
categories: [TCP/IP,Interview]
tags: [TCP/IP]
redirect_from:
  - /2018/4/18/
---

> 本文主要讲解TCP协议建立连接("3次握手")和断开连接("4次挥手")的过程

* Kramdown table of contents
{:toc .toc}

# TCP和UDP简介
TCP和UDP是TCP/IP协议簇传输层的协议工作在OSI的第四层
* TCP是面向连接的可靠的传输协议，有确认机制，重传机制，滑动窗口等
* UDP是无连接的尽最大努力的交付，应用层面来确保可靠性


# TCP报文格式
![smiley](https://img-blog.csdn.net/20140609125220296?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvYTE5ODgxMDI5/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)


* 重点字段介绍
	* 1.序号：Seq序号，占32位，用来表示从TCP源端向目的端发送的数据流，发起方发送数据时对此进行标记
	* 2.确认序号：Ack序号，占32位，只有ACK标志为1时，确认序号字段才有效，Ack=Seq+1
	* 3.标志位：共6个，即URG，ACK，PSH，RST，SYN，FIN等，具体含义如下：
		* URG：紧急指针有效
		* ACK：确认序号有效
		* PSH：接收方应该尽快将这个报文交给应用层
		* RST：连接重置
		* SYN：发起一个新连接
		* FIN：释放一个连接

> * 需要注意:
>   * 不要将确认序号Ack与标志位中的ACK搞混了
>   * 确认方Ack=发起方Req+1，两端配对

# TCP连接的建立(三次握手)
![TCP Establish](https://img-blog.csdn.net/20170607205709367?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXpjc3U=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)<commit_msg>commit<commit_after>---
layout: post
title: "TCP三次握手和四次挥手"
description: "TCP三次握手和四次挥手"
categories: [TCP/IP,Interview]
tags: [TCP/IP]
redirect_from:
  - /2018/4/18/
---

> 本文主要讲解TCP协议建立连接("3次握手")和断开连接("4次挥手")的过程

* Kramdown table of contents
{:toc .toc}

# TCP和UDP简介
TCP和UDP是TCP/IP协议簇传输层的协议工作在OSI的第四层
* TCP是面向连接的可靠的传输协议，有确认机制，重传机制，滑动窗口等
* UDP是无连接的尽最大努力的交付，应用层面来确保可靠性


# TCP报文格式
![smiley](https://img-blog.csdn.net/20140609125220296?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvYTE5ODgxMDI5/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)


* 重点字段介绍
	* 1.序号：Seq序号，占32位，用来表示从TCP源端向目的端发送的数据流，发起方发送数据时对此进行标记
	* 2.确认序号：Ack序号，占32位，只有ACK标志为1时，确认序号字段才有效，Ack=Seq+1
	* 3.标志位：共6个，即URG，ACK，PSH，RST，SYN，FIN等，具体含义如下：
		* URG：紧急指针有效
		* ACK：确认序号有效
		* PSH：接收方应该尽快将这个报文交给应用层
		* RST：连接重置
		* SYN：发起一个新连接
		* FIN：释放一个连接

> * 需要注意:
>   * 不要将确认序号Ack与标志位中的ACK搞混了
>   * 确认方Ack=发起方Req+1，两端配对

# TCP连接的建立(三次握手)

##TCP连接建立流程图
![TCP Establish](https://img-blog.csdn.net/20170607205709367?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXpjc3U=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)

##TCP连接建立过程详解
所谓三次握手（Three-Way HandShake）即建立TCP连接，就是指建立一个TCP连接时，需要客户端和服务端共发送3个包以确认连接的建立。在Socket编程中，这一过程由客户端执行connect来触发，流程详解如下：
* 1.第一次握手
	Client将标志位SYN置为1，随机产生一个值Seq=x，并将改数据包发送给Server，Client进入SYN_SENT状态，等待Server确认
	
* 2.第二次握手
	Server收到数据包后由标志位SYN=1知道Client请求简历连接，Server将标志位SYN和ACK都置为1，ack=x+1，随机产生一个seq=y，并将该数据包发送给Client以确认连接请求，S	erver进入SYN_RCVD状态。
	
* 3.第三次握手
	Client收到确认后，检查ack是否为x+1，ACK是否为1，如果正确则将标志位ACK置为1，ack=y+1，并将该数据包发送给Server，Server检查ack是否是y+1，ACK是否为1，如果正确	则连接建立成功，Client和Server进入ESTABLISHED状态，完成三次握手，随后Client与Server之间可以开始传输数据了。


SYN攻击：
在三次握手的过程中，Server发送了SYN-ACK后，收到Client的ACK之前的TCP连接称为半连接（half open connect），此时Server处于SYN_RCVD状态，当收到ACK后，Server转入ESTABLISHED状态。SYN攻击就是Client在短时间内伪造大量不存在的IP地址，并向Server不断发送SYN包，Server回复确认包，并等待Client确认，由于源地址是不存在的，因此Server需要不断重发直至超时，这些伪造的SYN包将长时间占用连接队列，导致正常的SYN请求因为队列满而被丢弃，从而引起网络拥塞甚至是系统瘫痪。SYN攻击是一种典型的DDOS攻击，检测SYN攻击的方式非常简单，即当Server上有大量半连接状态且源IP地址是随机的，则可以断定遭到了SYN攻击了，在linux系统上可以使用如下命令检测当前处于SYN_RCVD的进程有哪些。
~~~ ruby
#netstat -nap | grep SYN_RECV
~~~

# TCP连接的关闭(四次挥手)

##TCP连接关闭流程图
![TCP Establish](https://img-blog.csdn.net/20170607205756255?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXpjc3U=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
{'fraction_non_alphanumeric': 0.12885398487492727, 'fraction_numerical': 0.06573589296102385, 'mean_word_length': 8.170666666666667, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 11, 'https://': 5, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5520403', 'n_tokens_mistral': 2507, 'n_tokens_neox': 2660, 'n_words': 108}