网络|学习一下tcp三次握手

简介: 网络|学习一下tcp三次握手

TCP报文结构


我们想要介绍TCP/IP三次握手,需要有个前置条件,我们得补充下相关背景,目前我们所使用的的网络协议为TCP/IP4层协议,从下往上即: 数据链路层、网络层、传输层 以及 应用层。


图示如下:


image.png


在使用网络进行数据发送过程中,会将数据进行封包操作,到了对方机器,会逐步解包。我们使用的TCP协议,则是在传输层上,我们一般将其数据称之为报文段。


在介绍TCP如何通过三次握手建立连接之前,还需要先看看其TCP报文段结构,图示如下:

image.png


TCP报文段由2部分组成,首部 (黄色+绿色)和数据报文(蓝色),其中首部又包含基本首部20字节(上图黄色部分) 和 选项部分(上图绿色部分) 最多40字节。


上述报文段中,

  • 源端口 和 目的端口

这2个没啥特别的意思,就是记录双方端口的,分别是2个字节,所以说,服务器的端口最大为65535,因为这是2的16次方还要减去一个数(这个数为0),所以是65535。


  • 序号 和 确认序号

分别占了4个字节,我们常听见的seqack以及seq_ack等都是指的它两。


  • 首部长度

首部长度,也称之为数据偏移,用来指定首部长度的,如前面所述,报文段固定首部20个字节,还有40个字节的选项部分,如该首部长度为5,则证明首部就20个字节(5*4个字节),该值最多为15,即60个字节。


  • 保留

占了3个字节,现在还没有启用。


  • 状态标志位

URGACKPSHRSTSYNFIN这些都是占用了一个位,用以标志该报文段的状态,这些标志位在启用的时候会置为1,不启用的时候会置为0。其中

  • SYN表示新建连接。
  • FIN表示释放连接。
  • ACK表示确认收到数据。
  • RST表示请求重发。
  • PSH表示紧急数据,需要尽快交付至应用层。
  • URG表示紧急数据,需优先发送。
  • 接收窗口:2个字节,用于告知对方接收窗口的大小,做流量控制使用。
  • 校验和:2个字节,会校验伪首部、首部以及数据三个部分。
  • 紧急指针:2个字节,当URG置为1的时候才有效,该数据会指出有多少字节需要紧急传输。
  • 可选项:最大为40字节,包括窗口缩放、MSSSACK、时间戳等。


以上就是整个tcp报文段的内容了,只是做了一个简单的概述。




tcp如何通过三次握手建立连接


假设主机A和主机B想要建立连接,在实际发送报文数据之前,需要先发送3个空包用于建立连接,建立连接和TCP的状态图示如下:

image.png


首先,在建立握手之前,服务器必须要优先于客户端启动服务,而后客户端才能进行连接。

当客户端第一次发起请求的时候,需将报文段SYN标志位置为1,并且指定一个随机数作为seq,此时客户端的状态为SYN SEND


当服务器收到客户端请求后,需将报文段中的SYNACK标志位置为1,并且指定一个随机数作为seqack_seq值为x+1,此时服务器的状态为SYN REVD


当客户端收到请求服务器请求后,此时客户端的状态为ESTABLISHED需将报文段中的ACK标志位置为1,seq值为x+1,ack_seq值为x+1。服务器接收到后,此时服务器的状态也为ESTABLISHED


至此,客户端和服务器已经成功建立连接。



使用tcpdump进行抓取一个会话包


上面已经简单介绍了什么tcp的前置只是 和 为什么需要三次握手,而不是两次,本段落就来介绍一下如何使用tcpdump进行抓包,抓包工具有很多,在windows下,你可以选择Wireshark,在linux你可以选择tcpdump。也可以在linux抓包后保存到文件中,再导入Wireshark打开。


前置条件:若我们想使用tcpdump抓取信息,需要提前建立一个tcp服务器才行,这里搭建了一个nginx服务器,index.html简单设置为了hello pdudo


如果你的操作系统没有安装tcpdump,那么需要使用yum来安装一下:

yum install tcpdump -y


使用man tcpdump可以获取更加详细的帮助文档,本篇文章需要用到的参数为如下几个:


-A: 以ascii码来显示报文。

-S: 输出TCP握手的全部信息,而非缩略信息。

-s num: 从每个数据包中抓取num字节的数据。

port: 指定从哪个端口抓取。

-i interface: 指定抓取的网口。


例如: 我们想抓取本地回环地址(lo)的80端口,以ASCII码的方式输出:

tcpdump -s 0 -S -A port 80 -i lo


抓取之后,结果为:

image.png

其中黄色线条框起来的地方就是三次握手的信息了。


如之前所述,可以清晰的看到,第一次握手信息是客户端发送给http服务器的,即: localhost.46452 > localhost.http


来解释一下请求的第一段报文信息:


  • Flags [S]: 表示报文的SYN标志位为1。
  • seq 532696697:表示seq为: 532696697 。
  • win 43690:表示滑动窗口为43690。
  • options存储的是TCP的选项信息,这是可变长信息,最大为40字节,内容为:
  • mss 65495mss表示每一个报文段所能支持的最大数据长度,这个只在握手的时候会进行协定,所以看后续的报文中,都没有出现mss相关信息。
  • sackOK
  • TS val 3302976138 ecr 0: 时间戳,用于测试报文往返时间。
  • wscale 7: 表示接收窗口
  • length:表示报文数据长度。


其他的,就不一一叙述了。


在结合之前的理论信息,我们可以知道:

当客户端第一次请求握手协议的时候,seq发送的是x2992020176

当服务器收到后,客户端发送上来的x+1作为ack返回,其值为2992020177,并且重新取了一个随机数y,其值为4127097599


当客户的接收到该数据后,向服务器发送了一个ack,并且还携带了seqseq_ack,只不过这里tcpdump给屏蔽了,使用其他抓包软件,例如 Wireshark 就可以正常显示出来。



在linux中如何查看连接状态


之前还介绍了tcp三次握手的状态信息,例如SYNC SENDSYNC REVD应该从哪儿看呢?注意,这个只是一个标准来规定它的状态,而不是存储在报文中,在linux中,可以使用netstatss等命令来查看当前服务器有哪些链接,这些链接分别是什么状态,例如:


ss -a | head -n 1 ; ss -a | grep ^tcp

上述命令表示展示当前机器所有的socket信息,并且使用grep过滤了一下以tcp开头的,我们能够得到如下截图:

image.png


上述截图中会显示当前机器的所有socket,包括服务器,如果是真实服务器,会有很多条信息,比如我们想赛选出当前服务器哪些状态分别有多少个,应该如何选择呢?


这里可以使用awk,将状态给存储到数组中,继而遍历出来即可,命令为:

ss -a | grep ^tcp | awk '{status[$2]=status[$2]+1} END{for (i in status) {print i,status[i]}}'

该命令为使用了awk将第二列的值当做数组的key给存上,当再次出现时,该数组key的值就+1,最后再遍历数组,就可以得到结果了,我们找台机器看下:

image.png


如果是使用的netstat命令,则需要取其最后一列用以awk计算。



linux对于tcp三次握手调整队列


对于tcp三次握手,linux中会用到2个队列,分别是 半连接队列 和 全连接队列。


其中半连接队列也称之为SYN队列,是指已经收到了客户端的请求,但是还没有建立完整连接,此时网络状态为SYN_REVD介于此linux会将该链接放入SYN队列中,并且等待客户端发送ACK报文以便建立连接。


而全连接队列也称之为Accept队列,该队列用于存储完成握手的连接,此时网络状态为ESTABLISHED,如果全连接队列满了,那么此时新链接上来会在SYNC_REVD处等待,等待全连接队列有空的出来,或者超时断开连接。


在linux中如何查看并且修改这2个值呢?


全连接队列的配置内核参数为net.core.somaxconn,而半连接内核参数为net.ipv4.tcp_max_syn_backlog ,使用sysctl可以查看并且修改2个值:

sysctl net.core.somaxconn
sysctl net.ipv4.tcp_max_syn_backlog


image.png

上述结果显示服务器全连接队列为最高为128,而半连接则为256


修改有2种方法:


  • 使用sysctl -w设置。
  • 将该值写入/etc/sysctl.conf中,并且使用sysctl -p使其重新加载。

例如: 修改全连接为1024,可以有2种方法:


方法1:

sysctl -w net.core.somaxconn=1024


方法2:

echo "net.core.somaxconn=1024" >> /etc/sysctl.conf && sysctl -p



总结


作为运维而言,网络和存储是必须且必要的知识,再结合linux调优,才能真正成为一名运维,在解决问题的过程中,特别是服务器性能过程中,是非常有意思的。运维不仅只是开关服务器以及背锅,还有其他更深层次有意义的事情等待运维去探索。




相关实践学习
深入解析Docker容器化技术
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。Docker是世界领先的软件容器平台。开发人员利用Docker可以消除协作编码时“在我的机器上可正常工作”的问题。运维人员利用Docker可以在隔离容器中并行运行和管理应用,获得更好的计算密度。企业利用Docker可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为Linux和Windows Server应用发布新功能。 在本套课程中,我们将全面的讲解Docker技术栈,从环境安装到容器、镜像操作以及生产环境如何部署开发的微服务应用。本课程由黑马程序员提供。     相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
相关文章
|
机器学习/深度学习 算法 数据挖掘
没发论文的注意啦!重磅更新!GWO-BP-AdaBoost预测!灰狼优化、人工神经网络与AdaBoost集成学习算法预测研究(Matlab代码实现)
没发论文的注意啦!重磅更新!GWO-BP-AdaBoost预测!灰狼优化、人工神经网络与AdaBoost集成学习算法预测研究(Matlab代码实现)
361 0
|
12月前
|
JavaScript Java 大数据
基于python的网络课程在线学习交流系统
本研究聚焦网络课程在线学习交流系统,从社会、技术、教育三方面探讨其发展背景与意义。系统借助Java、Spring Boot、MySQL、Vue等技术实现,融合云计算、大数据与人工智能,推动教育公平与教学模式创新,具有重要理论价值与实践意义。
|
网络协议 物联网
VB6网络通信软件上位机开发,TCP网络通信,读写数据并处理,完整源码下载
本文介绍使用VB6开发网络通信上位机客户端程序,涵盖Winsock控件的引入与使用,包括连接服务端、发送数据(如通过`Winsock1.SendData`方法)及接收数据(利用`Winsock1_DataArrival`事件)。代码实现TCP网络通信,可读写并处理16进制数据,适用于自动化和工业控制领域。提供完整源码下载,适合学习VB6网络程序开发。 下载链接:[完整源码](http://xzios.cn:86/WJGL/DownLoadDetial?Id=20)
634 12
|
负载均衡 网络协议 算法
不为人知的网络编程(十九):能Ping通,TCP就一定能连接和通信吗?
这网络层就像搭积木一样,上层协议都是基于下层协议搭出来的。不管是ping(用了ICMP协议)还是tcp本质上都是基于网络层IP协议的数据包,而到了物理层,都是二进制01串,都走网卡发出去了。 如果网络环境没发生变化,目的地又一样,那按道理说他们走的网络路径应该是一样的,什么情况下会不同呢? 我们就从路由这个话题聊起吧。
770 4
不为人知的网络编程(十九):能Ping通,TCP就一定能连接和通信吗?
|
人工智能 网络协议 IDE
使用通义灵码AI高效学习muduo网络库开发指南
Muduo 是一个基于 C++11 的高性能网络库,支持多线程和事件驱动,适用于构建高效的服务器和应用程序。它提供 TCP/IP 协议支持、异步非阻塞 I/O、定时器、异步日志等功能,并具备跨平台特性。通过 Git 克隆 muduo 仓库并切换至 C++17 分支可开始使用。借助 AI 工具如 Deepseak-v3,用户可以更便捷地学习和理解 Muduo 的核心模块及编写测试用例,提升开发效率。
|
网络协议 安全 NoSQL
网络空间安全之一个WH的超前沿全栈技术深入学习之路(8-2):scapy 定制 ARP 协议 、使用 nmap 进行僵尸扫描-实战演练、就怕你学成黑客啦!
scapy 定制 ARP 协议 、使用 nmap 进行僵尸扫描-实战演练等具体操作详解步骤;精典图示举例说明、注意点及常见报错问题所对应的解决方法IKUN和I原们你这要是学不会我直接退出江湖;好吧!!!
网络空间安全之一个WH的超前沿全栈技术深入学习之路(8-2):scapy 定制 ARP 协议 、使用 nmap 进行僵尸扫描-实战演练、就怕你学成黑客啦!
|
网络协议 安全 算法
网络空间安全之一个WH的超前沿全栈技术深入学习之路(9):WireShark 简介和抓包原理及实战过程一条龙全线分析——就怕你学成黑客啦!
实战:WireShark 抓包及快速定位数据包技巧、使用 WireShark 对常用协议抓包并分析原理 、WireShark 抓包解决服务器被黑上不了网等具体操作详解步骤;精典图示举例说明、注意点及常见报错问题所对应的解决方法IKUN和I原们你这要是学不会我直接退出江湖;好吧!!!
网络空间安全之一个WH的超前沿全栈技术深入学习之路(9):WireShark 简介和抓包原理及实战过程一条龙全线分析——就怕你学成黑客啦!
|
网络协议
TCP报文格式全解析:网络小白变高手的必读指南
本文深入解析TCP报文格式,涵盖源端口、目的端口、序号、确认序号、首部长度、标志字段、窗口大小、检验和、紧急指针及选项字段。每个字段的作用和意义详尽说明,帮助理解TCP协议如何确保可靠的数据传输,是互联网通信的基石。通过学习这些内容,读者可以更好地掌握TCP的工作原理及其在网络中的应用。
|
网络协议 测试技术 Linux
Golang 实现轻量、快速的基于 Reactor 模式的非阻塞 TCP 网络库
gev 是一个基于 epoll 和 kqueue 实现的高性能事件循环库,适用于 Linux 和 macOS(Windows 暂不支持)。它支持多核多线程、动态扩容的 Ring Buffer 读写缓冲区、异步读写和 SO_REUSEPORT 端口重用。gev 使用少量 goroutine,监听连接并处理读写事件。性能测试显示其在不同配置下表现优异。安装命令:`go get -u github.com/Allenxuxu/gev`。
500 0
|
监控 网络协议 网络性能优化
网络通信的核心选择:TCP与UDP协议深度解析
在网络通信领域,TCP(传输控制协议)和UDP(用户数据报协议)是两种基础且截然不同的传输层协议。它们各自的特点和适用场景对于网络工程师和开发者来说至关重要。本文将深入探讨TCP和UDP的核心区别,并分析它们在实际应用中的选择依据。
1096 3

热门文章

最新文章