网络编程-从TCP连接的建立说起 tcp连接的建立过程包括几个步骤
lipiwang 2024-10-25 15:50 32 浏览 0 评论
前言
网络编程几乎是每一门编程语言都会涉及的内容,虽然各种语言调用的方式可能不一样,但它们背后的原理支持都是一样的。因此本文将从TCP的连接的建立说起。在此之前,假设你已经对计算机网络有了最基本的认识。
网络编程做什么
当下网络应用数不胜数,如微信,可以让你通过网络与远在异国他乡的朋友交流沟通;如在线视频,让你通过网络就可以观看你喜欢的视频,而这一切的背后,都有网络编程技术的支持。通俗来讲,可以认为网络编程是两台或者多台主机(应用)之间进行数据交换或传输。
TCP:传输控制协议
而数据交换需要按照一定的规则,而这种规则就是协议。只有按照约定的规则,双方之间才能正确地进行数据交换。而TCP就是这些协议的一种,它提供一种面向连接的,可靠的字节流服务。
- 面向连接:两个使用TCP的应用在交换数据之前必须先建立一个TCP连接
- 可靠的:TCP有很多机制来尽可能的保证数据不丢失
- 字节流: 不区分是ASCII字符还是二进制数据,数据解释交给应用层
为什么要理解TCP
事实上不理解TCP背后的基本原理,仍然可以写出代码,但是当你遇到一些奇奇怪怪的而通过API的说明又无法解决的问题时,你就会庆幸自己花了点时间去学习TCP了。
TCP连接的建立
关于TCP连接的建立,你可能早已耳熟能详,其流程倒背如流。但我觉得还是有必要再理一理。TCP连接的建立,也就是三次握手的流程如下:
我们再试着描述一下三次握手的过程:
- 服务端启动,并暂停等待,处于LISTEN状态
- 客户端发起连接请求,发送序列号seq=X,处于SYN_SENT状态
- 服务端收到后,并回应ACK=X+1和seq=Y,处于SYN_RCVD状态,客户端发送能力,服务端接收能力正常。
- 客户端收到服务端的ACK,连接建立,同时向服务端回复ACK,处于ESTABLISHED状态
- 服务端收到ACK,连接建立,处于ESTABLISHED状态,客户端接收能力正常。
至此三次握手完成。需要注意的是,这是正常流程下的三次握手。而前面所说的这些状态可以通过netstat命令或者ss命令查看到,当然有些状态的存在时间比较短,可能无法观察到。
好了,那么问题来了:
- 为什么要三次握手
- 连接到一个不存在的端口会发生什么
- 连接到一个不存在的服务器主机会发生什么
- 初始seq是如何变化的
- 半连接队列是什么
- SYN攻击是什么
如果以上所有问题你都能轻而易举地回答出来,那么本文后面的内容你可以跳过了。
为什么要三次握手
这几乎是面试中必问的一个问题。一个TCP连接是全双工的,即数据在两个方向上能同时传输。因此,建立连接的过程也就必须确认双方的收发能力都是正常的。
四次握手是否可以呢?完全可以!但是没有必要!在服务端收到SYN之后,它可以先回ACK,再发送SYN,但是这两个信息可以一起发送出去,因此没有必要。
两次握手是否可以呢?想象这样一种情况,客户端发起了一个连接请求在网络中滞留了很长时间,以至于在连接建立好且断开连接后,它才到达服务端,此时如果采用两次握手,那么服务端就会认为这个报文是新的连接请求,于是建立连接,等待客户端发送数据,但是实际上客户端根本没有发出建立请求,也不会理睬服务端,因此导致服务端空等而浪费资源。
为什么服务器会认为这个迟到的报文是新的连接请求?因为如果采用两次握手机制,那么服务端无法通过SYN来判断这是一个迟到或者重复的报文,还是正常到达的报文,但是对于三次握手,即便出现这样的情况,也不会在服务端建立起真正的连接。
一个正常的连接三次握手
我们利用tcpdump命令和nc命令来观察一个正常的tcp连接建立过程。首先在终端1准备抓包:
|
|
在终端2启动监听1234端口:
|
|
在终端3连接:
|
|
在终端1得到以下输出内容:
|
|
从上面抓包内容可以看到,总共有三个报文,分别是客户端发送到服务端的SYN,服务端回应给客户端的SYN和ACK,以及客户端回应给服务端的ACK。
连接到一个不存在的端口
如果要连接的服务器端口不存在会出现什么情况呢?我们利用nc命令来抓包观察。
在一个终端窗口使用管理员权限执行下面的命令进行抓包,并打印相关信息:
|
|
在另外一个终端使用nc命令尝试连接到本地的1234端口
|
|
TCP抓包内容如下:
|
|
从抓包内容中可以看到,首先nc客户端发送一个SYN(Flags为S),seq为1175796450。而后收到一个RST(Flags为R),seq为1175796451。
也就是说,如果连接到一个不存在的端口,服务端所在的系统会响应一个RST(复位),直接终止连接。
Flags字段含义如下:
- F : FIN - 结束; 结束会话
- S : SYN - 同步; 表示开始会话请求
- R : RST - 复位;中断一个连接
- P : PUSH - 推送; 数据包立即发送
- A : ACK - 应答
- U : URG - 紧急
- E : ECE - 显式拥塞提醒回应
- W : CWR - 拥塞窗口减少
连接到一个不存在的服务器
同样是利用nc和tcpdump命令。
|
|
在另外一个窗口使用nc命令连接到一个不存在的或者无法连接的服务器地址:
|
|
tcpdump输出内容如下:
|
|
通过实际操作可以发现,当发送第一个SYN没有响应时,客户端会再次发送;如果还是没有响应,再隔更长一段时间,继续发送SYN,最终连接超时。从观察情况来看,默认会进行5次重发,5次的重试时间间隔分别为1s, 2s, 4s, 8s, 16s。
初始序列号是如何变化的
通过前面的两次抓包可以看到,发送第一个SYN请求的初始序列号seq并不是固定的。实际上,不同的系统它的生成方法可能不同,但是可以知道的是,它在一定时间内,生成seq值肯定不同,否则服务端无法区分这到底是同一个seq的重发还是这个报文在网络中滞留一段时间后又重新到达。RFC 793指出初始序列号可以可看成一个32位的计数器,每隔4ms加1(但不同系统实际实现又可能不太一样,为了安全起见会处理成随机值),因此当它重新回到开始的时候,已经过了够长时间,使得网络中延迟的报文早已消失。
半连接队列
在服务器收到客户端的连接请求,并发送ACK之后,服务端处于SYN_RECV状态,此时的连接成为半连接,服务器会将半连接放到一个名为半连接队列的地方。
SYN攻击
正因如此,如果有人恶意地向服务器发送大量的SYN包,并且由于客户端IP是伪造的,导致服务器收不到ACK,不断重发ACK,以至于半连接队列容易占满,导致无法处理正常的连接请求,并且可能导致服务器资源耗尽。
如何处理SYN攻击又是另外一个话题。
总结
TCP三次握手的正常场景我们很容易描述出来,但是涉及更多细节以及异常场景的时候,我们可能不是那么熟悉,通过本文可以简单地了解TCP连接的建立,为后面的网络编程打下基础。但是需要说明的是,本文仅仅简单介绍了TCP连接的建立,并没有深入介绍。
- 上一篇:TCP可靠传输的一点知识 tcp可靠传输的原理
- 下一篇:少妇白洁
相关推荐
- 前端入门——css 网格轨道详细介绍
-
上篇前端入门——cssGrid网格基础知识整体大概介绍了cssgrid的基本概念及使用方法,本文将介绍创建网格容器时会发生什么?以及在网格容器上使用行、列属性如何定位元素。在本文中,将介绍:...
- Islands Architecture(孤岛架构)在携程新版首页的实践
-
一、项目背景2022,携程PC版首页终于迎来了首次改版,完成了用户体验与技术栈的全面升级。作为与用户连接的重要入口,旧版PC首页已经陪伴携程走过了22年,承担着重要使命的同时,也遇到了很多问题:维护/...
- HTML中script标签中的那些属性
-
HTML中的<script>标签详解在HTML中,<script>标签用于包含或引用JavaScript代码,是前端开发中不可或缺的一部分。通过合理使用<scrip...
- CSS 中各种居中你真的玩明白了么
-
页面布局中最常见的需求就是元素或者文字居中了,但是根据场景的不同,居中也有简单到复杂各种不同的实现方式,本篇就带大家一起了解下,各种场景下,该如何使用CSS实现居中前言页面布局中最常见的需求就是元...
- CSS样式更改——列表、表格和轮廓
-
上篇文章主要介绍了CSS样式更改篇中的字体设置Font&边框Border设置,这篇文章分享列表、表格和轮廓,一起来看看吧。1.列表List1).列表的类型<ulstyle='list-...
- 一文吃透 CSS Flex 布局
-
原文链接:一文吃透CSSFlex布局教学游戏这里有两个小游戏,可用来练习flex布局。塔防游戏送小青蛙回家Flexbox概述Flexbox布局也叫Flex布局,弹性盒子布局。它决定了...
- css实现多行文本的展开收起
-
背景在我们写需求时可能会遇到类似于这样的多行文本展开与收起的场景:那么,如何通过纯css实现这样的效果呢?实现的难点(1)位于多行文本右下角的展开收起按钮。(2)展开和收起两种状态的切换。(3)文本...
- css 垂直居中的几种实现方式
-
前言设计是带有主观色彩的,同样网页设计中的css一样让人摸不头脑。网上列举的实现方式一大把,或许在这里你都看到过,但既然来到这里我希望这篇能让你看有所收获,毕竟这也是前端面试的基础。实现方式备注:...
- WordPress固定链接设置
-
WordPress设置里的最后一项就是固定链接设置,固定链接设置是决定WordPress文章及静态页面URL的重要步骤,从站点的SEO角度来讲也是。固定链接设置决定网站URL,当页面数少的时候,可以一...
- 面试发愁!吃透 20 道 CSS 核心题,大厂 Offer 轻松拿
-
前端小伙伴们,是不是一想到面试里的CSS布局题就发愁?写代码时布局总是对不齐,面试官追问兼容性就卡壳,想跳槽却总被“多列等高”“响应式布局”这些问题难住——别担心!从今天起,咱们每天拆解一...
- 3种CSS清除浮动的方法
-
今天这篇文章给大家介绍3种CSS清除浮动的方法。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。首先,这里就不讲为什么我们要清楚浮动,反正不清除浮动事多多。下面我就讲3种常用清除浮动的...
- 2025 年 CSS 终于要支持强大的自定义函数了?
-
大家好,很高兴又见面了,我是"高级前端进阶",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发!1.什么是CSS自定义属性CSS自...
- css3属性(transform)的一个css3动画小应用
-
闲言碎语不多讲,咱们说说css3的transform属性:先上效果:效果说明:当鼠标移到a标签的时候,从右上角滑出二维码。实现方法:HTML代码如下:需要说明的一点是,a链接的跳转需要用javasc...
- CSS基础知识(七)CSS背景
-
一、CSS背景属性1.背景颜色(background-color)属性值:transparent(透明的)或color(颜色)2.背景图片(background-image)属性值:none(没有)...
- CSS 水平居中方式二
-
<divid="parent"><!--定义子级元素--><divid="child">居中布局</div>...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- maven镜像 (69)
- undefined reference to (60)
- zip格式 (63)
- oracle over (62)
- date_format函数用法 (67)
- 在线代理服务器 (60)
- shell 字符串比较 (74)
- x509证书 (61)
- localhost (65)
- java.awt.headless (66)
- syn_sent (64)
- settings.xml (59)
- 弹出窗口 (56)
- applicationcontextaware (72)
- my.cnf (73)
- httpsession (62)
- pkcs7 (62)
- session cookie (63)
- java 生成uuid (58)
- could not initialize class (58)
- beanpropertyrowmapper (58)
- word空格下划线不显示 (73)
- jar文件 (60)
- jsp内置对象 (58)
- makefile编写规则 (58)