从编程角度看TCP协议(4)python与tcp的三次握手

本文深入解析TCP连接特性及三次握手过程,包括其状态机变化、参数协商及Python实现方式,对比UDP无连接特性,阐述TCP的流控机制与选择确认机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1 tcp的连接特性

    对于tcp或者udp稍微了解一点的同学,肯定知道一句话,tcp是基于连接的,而udp是无连接的。怎么理解这句话呢?

    无论tcp还是udp,都是用来传输数据的一种协议,都处于网络层之上的传输层。也都需要通信双方的重新向操作系统申请端口,这是通信的前提。

    但不一样的是,udp发送方收到上层应用层程序(不一定非得是应用层协议,也可以自己写的网络程序)需要发送的数据后,直接发送出去,无论接收方是否收到,反正有数据给我,我就发送。

    而tcp在发送数据之前,是需要先通过三次握手建立连接的。在发送过程中,要求收到数据后的一方回复ACK,以示收到数据。发送完成后,可以通过四次挥手关闭连接,也可以维持连接等待下一次数据的发送(也就是所谓的TCP长连接)。

    还有一点要说明的是,udp跟ip协议是不区分客户端和服务器的,也就是说它提供的是P2P的通信。虽然我们平时所见的,基于udp上的dns、tftp、dhcp、radius等等应用层协议有客户端和服务器之分,那那也是应用层协议自己设计如此,udp本身是不区分的。

    tcp是区分客户端和服务器的,三次握手建立连接的过程,一定是客户端主动发起的,而服务器是被动响应。四次挥手拆掉连接的过程,既可以是客户端主动发起,也可以是服务器主动发起。只要一方没有数据发送给对端,那么就可以主动关闭连接,而不管你是客户端还是服务器。

    正是因为有连接的建立和关闭过程,因此tcp引入了状态机的概念,当客户端或者服务器发送或者接收到不同的报文时,就进入不同的状态。

2 三次握手

2.1 三次握手的状态机

    我们先看三次握手建立连接时,报文的交互和状态机的变化,如下图:

å»ºç« TCP è¿æ¥

2.2 python如何控制tcp三次握手

可以看到,对于客户端而言:

  (1)当上层程序要通过tcp发送数据时,会调用一个方法【比如python的的socket.connect()】,通知tcp发送数据包【SYN】建立连接,并把状态机改为【SYN-SENT】状态;

  (2)当客户端tcp收到服务端tcp的数据包【SYN/ACK】时,改变状态机到【ESTABLISHED】状态,表示从客户端到服务器的连接已经成功建立起来。

    对于服务器而言:

  (1)上层程序如果需要对外提供tcp服务时,会调用方法【比如python中的socket.bind((ip, port))】向tcp申请一个端口,ip是向操作系统申请,可以是一个网卡的ip,也可以是所有网卡的ip。申请成功后,继续调用方法【比如python中的socket.listen()】开始在tcp分配的端口上,监听客户端发来的连接建立请求,tcp会把状态机改为【Listen】状态;

  (2)当服务器tcp收到客户端的数据包【SYN】后,就会切换状态机到【SYN-RCVD】状态,并立即回复【SYN/ACK】报文;

  (3)当服务器tcp收到客户端的回复报文【ACK】后,改变状态机到【ESTABLISHED】状态,表示从服务器到客户端的连接已经成功建立起来。

2.3 三次握手时协商了哪些参数

    如上图所示,为客户端【10.140.6.44】与服务器【10.74.97.122】三次握手的报文--【SYN】【SYN/ACK】【ACK】。三次握手除了建立双向的tcp连接以外,其实客户端和服务器还协商了各自支持的一些参数,参数的协商是通过【SYN】和【SYN/ACK】报文来完成的。

2.3.1 SYN报文中,【Flags】字段中的【SYN】标志位置为1,表示这是SYN报文。

    在TCP固定头部里的【Window size value】,表示客户端通过此SYN报文告诉服务器,自己此刻接收窗口的大小。这是TCP的流控机制里面一个参数,后文会讲。另外TCP的【Options】字段出现了,一般都会携带【MSS】、【SACK】、【NOP】字段。

    【MSS】  :占4个字节,客户端用此字段告诉服务器,自己发送的TCP数据段的最大长度,以字节为单位;

    【SACK】:占2个字节,客户端用此字段告诉服务器,自己支持SACK,即选择确认机制,后文会讲;

    【NOP】  :占1个字节,由于【Options】被定义为4字节的整数倍,因此如果出现非4字节的option时,用此option实现4字节对齐;

2.3.2 SYN/ACK报文中,它的【Flags】字段中的【SYN】和【ACK】标志位都被置为1,表示这是SYN/ACK报文。

    在TCP固定头部里的【Window size value】,表示服务器通过此SYN/ACK报文告诉客户端,自己此刻接收窗口的大小,流控机制是双向的,任何一个TCP报文都会存在。

    由于SYN报文出现了【Options】字段,因此SYN/ACK也会利用【Options】来与SYN协商参数,如果支持就回复自己对应字段的值,如果不支持此字段,就为空。

2.4 三次握手的python实现

    我们可以通过python来调用tcp收发数据,即通过前文中的【socket.recv()】和【socket.sendall()】方法控制tcp收发数据。但是,这两个方法我们都没有提供目的ip和端口,数据往谁发送,又是从哪里接收数据?

    其实这也说明了tcp的连接特性,我们在收发数据之前,是需要提前建立连接,在建立连接的过程中,我们会提供目的ip和端口。当然了,tcp是不会主动帮你应用程序建立连接的,需要你调用对应的方法,它才能帮你做事。

    如下所示,为服务器向tcp申请端口,并监听连接的代码。

# !/usr/bin python3
import socket
import contextlib
import logging


@contextlib.contextmanager
def server_prepare_conn(ip, port, backlog=5):
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as tcp_sk:
        logging.debug("Try to apply for one port from os......")
        try:
            tcp_sk.bind((ip, port))
        except Exception:
            raise
        else:
            tcp_sk.listen(backlog)
            logging.debug("Succeeded to apply one port from os")

        try:
            yield tcp_sk
        except Exception:
            raise

    如下所示,为客户端要求tcp建立连接的代码。

# !/usr/bin python3
import socket
import contextlib
import logging


@contextlib.contextmanager
def client_setup_conn(ip, port):
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as tcp_sk:
        logging.debug("Try to setup a connection......")
        try:
            tcp_sk.connect((ip, port))
        except Exception:
            raise
        else:
            logging.debug("Succeeded to setup a connection")

        try:
            yield tcp_sk
        except Exception:
            raise

 

 

<think>嗯,用户想学习编程来搭建跨境电商独立站,但完全不懂编程,需要制定一个系统性的学习计划。首先,我得了解搭建独立站需要哪些技术栈。通常来说,前端需要HTML、CSS、JavaScript,后端可能需要PHP、Python或者Node.js,数据库的话MySQL或者MongoDB,还有服务器管理、支付接口、安全措施等等。 用户是零基础,所以得从最基础的编程概念开始。但也不能太理论,否则容易失去兴趣。应该结合实践,逐步引导。比如先学HTML和CSS,让用户能马上看到页面效果,增加成就感。然后JavaScript,让页面动态起来,接着后端语言,比如Python,因为相对容易入门,搭配框架如Django或Flask。数据库部分,先学SQL基础,再学ORM。之后教他们如何整合支付和物流API,最后部署到服务器。 还要考虑用户的目标是电商网站,所以需要涵盖电商特有的功能,比如商品管理、购物车、用户认证、支付网关、订单处理等。可能还需要介绍一些现有的电商平台或框架,比如Magento、Shopify,但用户想要自己搭建,所以应该用开源解决方案,比如WooCommerce或者基于Python的Saleor。 另外,用户可能需要了解一些前端框架,比如React或Vue,来提升用户体验,但作为初学者,可能先掌握基础再进阶。同时,版本控制工具Git也是必须的,方便代码管理。 需要分阶段规划,每个阶段有明确的目标和项目,比如第一阶段做静态页面,第二阶段增加交互,第三阶段实现后端逻辑,第四阶段整合数据库,最后完成整个电商功能并部署。还要推荐一些学习资源和练习项目,比如freeCodeCamp、Codecademy,以及实战项目如克隆一个简单电商网站。 还要注意时间安排,预估每个阶段的学习时间,比如每周10-15小时,持续6个月左右。提醒用户保持实践,参与社区,遇到问题如何解决,比如Stack Overflow、GitHub等。最后强调持续学习和迭代的重要性,因为技术会更新,需求也可能变化。</think>我将为你制定一个分阶段、循序渐进的学习计划,共分为6个阶段,预计需要6-8个月(每周投入10-15小时): # 第一阶段:编程基础(4-6周) ## 1. 计算机基础 - 学习内容:计算机组成原理、HTTP协议基础、域名解析原理 - 实践:注册域名(Namecheap/阿里云),了解DNS设置 - 推荐资源:MDN Web Docs「HTTP概述」 ## 2. HTML/CSS 基础 - 核心技能: - HTML5语义化标签 - CSS盒模型与Flex布局 - 响应式设计基础 - 媒体查询@media - 项目实践: 1. 制作商品详情页 2. 设计注册/登录表单 3. 克隆Amazon首页布局 # 第二阶段:前端开发(6-8周) ## 1. JavaScript 基础 - 学习路径: 1. ES6语法(let/const、箭头函数) 2. DOM操作 3. AJAX与Fetch API 4. 模块化开发 - 重点掌握: ```javascript // 示例:实现商品加入购物车功能 class Cart { constructor() { this.items = JSON.parse(localStorage.getItem('cart')) || []; } addItem(product) { const existing = this.items.find(item => item.id === product.id); existing ? existing.quantity++ : this.items.push({...product, quantity:1}); this._saveToStorage(); } _saveToStorage() { localStorage.setItem('cart', JSON.stringify(this.items)); } } ``` ## 2. 前端框架(React) - 必学内容: - JSX语法 - 组件生命周期 - React Router - 状态管理(Context API) - 实战项目:开发商品分类导航组件 # 第三阶段:后端开发(8-10周) ## 1. Node.js 基础 - 核心技术: - Express框架 - RESTful API设计 - 中间件机制 - JWT认证 - 示例代码: ```javascript // 商品API路由 app.get('/api/products', async (req, res) => { try { const { category } = req.query; const products = await Product.find(category ? { category } : {}); res.json(products); } catch (err) { res.status(500).json({ error: 'Server error' }); } }); ``` ## 2. 数据库(MongoDB) - 学习重点: - 文档型数据库设计 - Mongoose ODM - 索引优化 - 事务处理 - 数据模型示例: ```javascript const productSchema = new mongoose.Schema({ name: { type: String, required: true }, price: { type: Number, min: 0 }, sku: { type: String, unique: true }, inventory: { type: Number, default: 0 }, categories: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Category' }] }); ``` # 第四阶段:电商核心功能开发(6-8周) ## 1. 支付系统集成 - 必接支付渠道: - PayPal(适合国际) - Stripe(信用卡支付) - 支付宝国际版 - 安全注意: - PCI DSS合规 - 使用第三方SDK - 永远不要存储信用卡信息 ## 2. 订单系统 - 核心流程: $$订单状态机 = \{ pending \rightarrow paid \rightarrow shipped \rightarrow delivered \} $$ - 需实现功能: - 库存实时扣减 - 订单取消/退款 - 物流追踪接口 # 第五阶段:部署与优化(4-6周) ## 1. 服务器部署 - 技术选型: - AWS EC2/Lightsail - Nginx反向代理 - PM2进程管理 - 部署步骤: 1. 购买云服务器 2. 安装Node.js环境 3. 配置HTTPS(Let's Encrypt) 4. 设置防火墙规则 ## 2. 性能优化 - 优化策略: - CDN加速静态资源 - 数据库索引优化 - 缓存策略(Redis) - 图片懒加载 - 代码压缩(Webpack) # 第六阶段:持续迭代(长期) 1. 监控系统: - 使用Sentry收集错误 - Google Analytics分析流量 2. SEO优化: - 结构化数据标记 - 生成sitemap.xml 3. 安全加固: - 定期备份数据库 - 实施CSP策略 - 防范XSS/CSRF攻击 # 学习资源推荐 1. 免费课程: - freeCodeCamp「Responsive Web Design」 - Codecademy「Learn JavaScript」 2. 书籍: - 《JavaScript高级程序设计》 - 《Node.js实战》 3. 工具链: - VS Code编辑器 - Postman API测试 - Git版本控制 # 注意事项 1. 每日代码量要求:初期≥100行,后期≥300行 2. 加入开发者社区(Stack Overflow/GitHub) 3. 定期代码Review(可找mentor或使用AI工具) 4. 不要过早追求完美,采用「最小可行产品」策略 这个计划需要投入约600-800小时的有效学习时间。建议从今天开始,先完成第一个HTML页面,每完成一个阶段就开发对应模块,最终整合成完整系统。过程中遇到具体技术问题,可以随时进一步提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值