带你了解 NIO 系列之 TCP 探秘

TCP层的分段和IP层的分片之间的关系 & MTU和MSS之间的关系 首先说明:数据报的分段和分片确实发生,分段发生在传输层,分片发生在网络层。但是对于分段来说,这是经常发生在UDP传输层协议上的情况,对于传输层使用TCP协议的通道来说,这种事情很少发生。 1,MTU(Maximum Transmission Unit,MTU),最大传输单元 (1)以太网和802.3对数据帧的长度都有一个限制,其最大 值分别是1500和1492个字节。链路层的这个特性称作MTU 阅读详情


IT技术之家 2018-06-27 21:45:00

很开心,上半年发布的spring boot 2中,默认的web 容器是netty ,这说明“反应式” 容器已经是大势所趋,无论是go 语言的协从线程,还是java 基于reactor 线程模型,都是基于事件编程实现高并发的实例。这周开始我会讲关于NiO的一切,底层原理是什么,应用架构有哪些,如何利用其优势构建高性能服务器,欢迎关注。

在介绍NIO之前有必要了解下TCP协议,因为目前多数应用都是给予应用层进行操作,导致隐藏了大量的网路细节,知道这些细节以及原理对我们的问题排查很有益处。

一、TCP 特性

TCP 是一种面向连接的协议,它给用户进程提供可靠的全双工的字节流。确保数据包的可靠,有序,以及支持流量控制。关于TCP 为何要做这些,我们从以下几个方面入手:

  • IP网络层为何不保证数据包的可靠性
  • TCP协议如何保证包可达、有序
  • TCP协议如何支持流量控制
  • TCP几种状态以及应用

二、IP网络层为何不保证数据包的可靠性

我们先看下OSI的网络分层,在以下分层中,TCP 位于传输层,它保证的是协议的可靠性和连续性。具体的收发报是有底层的链路层以及物理层所决定的,所以TCP 所做的工作,也是基于底层的优化和改进。

带你了解 NIO 系列之 TCP 探秘

客户端与服务器之间的通信使用应用协议,传输层的通信采用TCP协议,而TCP 协议又采用了更低的一层IP协议,IP则使用某种形式的数据链路层通信。

带你了解 NIO 系列之 TCP 探秘

我们知道网络的中的数据,最终通过多个路由器连接传送的。最底层的以太网协议规定了电子信号如何组成数据包,解决了局域网的点对点通信问题,但无法解决多个局域网的的互通问题。

而网络层采用的IP协议,就是定义了一套自己的地址规则,主要解决寻址和路由的功能,根据对方的IP地址,寻找最佳路径传输信息。局域网通过路由器连接,路由器基于IP协议,指导数据包向某个路由借口转发。但IP协议不保证包一定到达以及完整性,特别是网络拥堵的时候,会丢弃一些数据包,保证数据的传送效率。

而保证数据包的完整、有序以及可靠,这就是TCP 协议要来做的事情了。

三、TCP 协议

1、TCP 包组成

很多网络有一个最大传送单元,它是链路层中的网络对数据帧的一个限制,以以太网为例,MTU为1500个字节。一个IP数据报在以太网中 传输,如果它的长度大于该MTU值,就要进行分片传输,使得每片数据报的长度小于MTU。

另外一个数据包还包含头信息,除了自己的Tcp包头,还有IP 头信息和以太网头信息。IP 数据包在以太网数据包的负载里面,最少需要20字节,所以 IP 数据包的负载最多为1480字节。

带你了解 NIO 系列之 TCP 探秘

那么tcp的一个包大小是多少呐?

我们需要机遇MSS这个值来确定,MSS是TCP里的一个概念(首部的选项字段中)。MSS是TCP数据包每次能够传输的最大数据分段,TCP报文段的长度大于MSS时,要进行分段传输。 如果不设置,则MSS的默认值就为536个字节 。也就是说一个tcp包的在500字节左右。

2、如何保证可靠性

上述也说了,底层的路由转发包,并不保证包的可靠性以及有序性。

首先为了保证包的完整性,TCP 会基于MSS 为大于 MSS的包进行分包处理,默认MSS大小为563byte,其大小小于MUT,以防止在网络层被分片处理。

其次增加SEQ和ACK,同时采用超时重发的机制来保证包的可靠性。

1)SEQ

为了保证有序性,TCP 为每个包编配一个Sequence number ,简称 SEQ 。以便接收的一方按照顺序还原。万一发生丢包,也可以知道丢失的是哪一个包。一般第一个包的编号是一个随机数,也可以从1开始。

2)ACK

那么有编号了,如何确保包一定到达?

基于ACK 进行确认。对于接收方来说,每次接受一个包必须返回ack信息,发送端从而确认这个包已经传送到。另外,接收方要对每一条报文做校验。如果校验发现出错,则不发送确认报文,从而触发发送方超时重传。

ACK 包含以下信息:

  • 期待要收到下一个数据包的编号 next SEQ
  • 接收方的接收窗口的剩余容量

我们采用wiershark抓包一个oschina的包看下三次握手的数据。

我的本机ip:192.168.1.103oschinaIp:116.211.174.177三次握手过程:1.me->osChina:syn=1 seq=x ack=02.osChina->me:syn=1 seq=y ack=x+13.me->osChina:seq=x+1 ack=y+1

1、me->osChina:syn=1 seq=0 ack=0

带你了解 NIO 系列之 TCP 探秘

2、osChina->me:syn=1 seq=0 ack=0+1

带你了解 NIO 系列之 TCP 探秘

3、me->osChina:seq=0+1 ack=0+1

带你了解 NIO 系列之 TCP 探秘

对比一下三次握手的过程。

带你了解 NIO 系列之 TCP 探秘

3)超时重传

我们知道网络极其不稳定,数据包即便增加了SEQ和ACK,能够保证其有序性,但依然保证丢包或者超时的问题。如果发送端发送数据,或者接收端回复ACK的消息在网络中丢失或者超时怎么处理?

RTO ,超时重传时间。要知道包是否出现超时,需要有一个评估方式,而RTT是对一个给定连接的往返时间的测量。由于网络流量的变化,这个时间会相应地发生改变,TCP需要跟踪这些变化并动态调整超时时间RTO。

发送方如果一定时间内没收到报文的ACK,就认为该报文丢失在网络中了,自动重发该报文。这种机制称之为超时重传。

在这期间,如果接收端的消息,由于丢失,接收端没有收到ack 消息,发送端会向接收端重发这个包。如果因为超时原因,发送端在超时定时器之后收到了这个包的ack 信息,而且发送端已经重复发送了这个消息,此时发送端不会处理,直接丢弃该ack 。而接收端接收到了之后会再次回复ack 信息。

四、流量控制

上述中我们知道了TCP协议可以保证数据的可靠性,但是也得兼顾效率。兼顾效率的话需要考虑以下三个方面:

  • 支持批量发包
  • 能够基于网络的状况,支持拥堵控制
  • 能够了解接收端的状况,防止接收端处理不过来

基于以上三个需求,做了以下处理。

1、滑动窗口

如果TCP 中的包,都需要发送一个确认一个的话,效率太低了,单次发送和确认一个包,虽然保证了可靠性,但无法保证其效率。此时需要一个批量发送和确认的方式,这就是滑动窗口所做的事情。

发送滑动窗口:

发送窗口从左向右移动在这个发送窗口之前的数据必然是已经发送而且得到接收方确认的数据落在发送窗口之内的数据是发送方可以发送的数据在发送窗口之后的数据是不能发送的数据。

如果发生超时或者丢失现象。那么有两种解决方案:

1、回退N,丢失的包号之后所有包都重发2、选择重传ARQ,只发丢失的,避免重复的(效率高,防止发送重复的)

滑动窗口还有一个作用是让发送端知道接收端的处理状况。假设TCP接收方的缓存已经满了,无法处理更多的,而发送方并不知道,每次会给对方告知当前滑动窗口的大小值 ,此时发送端就不会再发送数据了。

  • 接收方接收到数据同样马上发送确认,但是同时对发送方宣布窗口大小为0。这样发送方就暂时不会发送数据。
  • 报文到达时不马上发送确认,直到缓存有足够的空间。这样就可以避免发送方滑动窗口。但是这也存在一个问题,接收方延迟发送确认的时间不应该超过超时时间,如果过长会导致发送方误以为数据丢失重新发送数据。

2、拥堵控制

我们知道网络状况有好友坏,好的时候,可以多发些包,坏的时候,如果发包速率不变的话,除了会加重网路负担以外,还会造成包的过多丢失,除非更多的超时重发,这无疑识降低了通信效率。

基于此,TCP通信双方维护一个叫做拥塞窗口(cwnd,congesion window)的值,这个值取决于网络中的拥塞率,发送方的发送窗口的值就等于拥塞窗口的大小。只要网络中没有出现拥塞,拥塞窗口的值就可以增大一些,这样发送方可以发送到网络中的数据就多一些。反之,拥塞窗口的值就减小,从而避免加剧网络的拥塞率。

TCP目前拥塞控制主要有以下4种算法:

  • 慢启动
  • 拥塞避免
  • 快速重传
  • 快恢复

具体的算法实现方式就不再介绍了,大概实现的功能就是,基于当前的网络状况,找到一个合适的发送速率,防止给网络造成过大的负担。比如说慢启动,就是开始的时候,发送得较慢,然后根据丢包的情况,调整速率:如果不丢包,就加快发送速度;如果丢包,就降低发送速度。

五、TCP 状态

了解TCP的都知道,TCP 建立连接的时候,有三次握手,断开链接的时候又四次握手交互。那么其中的状态是有哪些?

带你了解 NIO 系列之 TCP 探秘

上面的图看着是不是太乱记不住,我们看看下面这张梳理一下,看看具体应用状态。

带你了解 NIO 系列之 TCP 探秘

从上面可以看到,连接建立成功的时候,其状态是ESTABLISHED 的。当接受端的状态为SYN—RECV的时候,表示接受端,已经回复第二次握手信息了,等待发送端再次确认。如果网络中遭受到大量的SYN 攻击,会存在大量的SYN_RECV 状态。此时可以定位这些问题IP ,通过防火墙过滤就能解决大量的假连接问题。

六、消失的连接——TIME_WAIT

在网络中,某一端主动关闭而没有通过四次握手关闭,此时tcp已经建立的通道是否还在,多久会关闭?此时的TCP 状态为TIME_WAIT ,可以想象,现实中经常出现这种状况,多数的关闭连接都是主动关闭而非通过协商通信关闭。那么此时关闭,若果再重连还能重连上之前的tcp 通道么,还是需要重现创建。

任何TCP实现必须为MSL选择一个值,默认是2分钟或者30秒,TIME_WAIT默认是2倍的MSL,持续时间在1-4分钟之间。MSL是IP数据包能在网络中存活的最长时间。

TIME_WAIT 存在的两个理由: 1、可靠的实现TCP全双工连接的终止 2、允许老的重复分节在网络中消失

TCP必须防止某个连接的老的重复分组在该连接已经终止后再现,从而被误解成属于同一连接的化身,有time_wait 足够长,是2倍的MSL的,那么足够让某个方向上的分组最多存活MSL秒就被丢弃。

从TIME_WAIT状态到CLOSED状态,有一个超时设置,这个超时设置是 2*MSL(RFC793定义了MSL为2分钟,Linux设置成了30s),如此超过了这个时间,当前的tcp通道就会被定义为关闭。

【Java TCP/IP Socket】基于NIO的TCP通信(含代码) NIO主要原理及使用     NIO采取通道(Channel)和缓冲区(Buffer)来传输和保存数据,它是非阻塞式的I/O,即在等待连接、读写数据(这些都是在一线程以客户端的程序中会阻塞线程的操作)的时候,程序也可以做其他事情,以实现线程的异步操作。    考虑一个即时消息服务器,可能有上千个客户端同时连接到服务器,但是在任何时刻只有非常少量的消息需要读取和分发(如果采用线程池或者一线程一客 阅读详情

相关推荐

合肥-NIO蔚来汽车JAVA开发

面试一面电话二面视频(需要写代码)视频一视频二视频三 一面电话 时长:30分钟 实际:25分钟的样子 难度:一般 Nacos注册中心原理 从raft选举到pull、push整个流程 Dubbo调用原理 首先跟面试官说了dubbo怎么把服务注册到nacos中,再到从nacos中获取注册服务列表,调用的几种方式和负载均衡算法 Dubbo中3个消费者、4个提供者共建立了多少个连接 这个题回答了好久,主要是前面问了nacos,还以为dubbo跟nacos建立了多少链接,后面面试官说消费者和提供

jic的博客 2830

TCP连接的最大数据包大小 ——Maximum Packet Size for a TCP Connection

传输控制协议(TCP)是在连接的网络上发送文件或消息的有用协议。每个文件在发送网络上被分割成数据包。数据包在到达接收网络时合并。TCP数据包的最大大小是64K(65535字节)。通常,数据包大小受到网络资源的最大传输单元(MTU)的限制。MTU是网络硬件设置的数据传输限制的最大大小。数据包大小不应超过MTU。在本教程中,我们将尝试解释这些术语背后的概念,并探索它们的各个方面。

usstmiracle的博客 9296

网络编程(一):TCP与UDP与NIO

目录 网络编程入门 网络编程概述【理解】 网络编程三要素【理解】 IP地址【理解】 InetAddress【应用】 端口和协议【理解】 UDP通信程序 UDP发送数据【应用】 UDP接收数据【应用】 UDP通信程序练习【应用】 UDP三种通讯方式【理解】 UDP组播实现【理解】 UDP广播实现【理解】 TCP通信程序 TCP发送数据【应用】 TCP接收数据【应用】 TCP程序练习【应用】 TCP程序文件上传练习【应用】 TCP程序服务器优化【应用】 NIO ...

weixin_46300935的博客 1150

【NIO系列】——之TCP探秘

很开心,上半年发布的spring boot 2中,默认的web 容器是netty ,这说明“反应式” 容器已经是大势所趋,无论是go 语言的协从线程,还是java 基于reactor 线程模型,都是基于事件编程实现高并发的实例。这周开始我会讲关于NiO的一切,底层原理是什么,应用架构有哪些,如何利用其优势构建高性能服务器,欢迎关注。在介绍NIO之前有必要了解下TCP协议,因为目前多数应用都是给予应...

weixin_34123613的博客 609

别只刷题了!我用834分经验告诉你,华为HCIP大数据考试(H13-723)这样准备更高效

本文分享了华为HCIP大数据认证(H13-723)834分通关的高效备考经验。通过分析考试动态、题库验证技巧和章节优先级策略,帮助考生超越单纯刷题,系统化掌握核心知识点。特别强调实时流处理和离线批处理等重点章节,提供黄金90分钟临场发挥策略,助力考生一次性通过考试。

weixin_38168786的博客 460

Unity开发微信小游戏,使用Addressables管理游戏资源(本地进行远程测试)

快速构建Unity微信小游戏 使用Addressables管理游戏资源 使用小皮助手在本地进行远程资源加载测试

the_vnas的博客 6391

讲讲 TCP 协议

一、概述 TCP 协议与 UDP 协议同属于传输层的协议。 二、TCP 数据包的大小 我们通过下图来进行说明: 通过上图我们可以知道TCP数据包(Header+Data)总长度为1480字节。 三、TCP 数据包的编号 一个 TCP 数据包大概 1400 多个字节,那么一次性发送大量数据,就必须分成多个包。比如,一个 10MB 的文件,需要发送 7100 多个包。发送的时候,TCP 协议为每个包编号(sequence number,简称 SEQ),以便接收方按照顺序还原(万一发生丢包,也可以知道丢失的是哪

cab5的博客 2614

UE4引擎分析获取UWord,GName,GetName,GObjectArray

UE4引擎具有很多固定特征和特性 所以我们在逆向UE4引擎开发的游戏的时候,可以利用这些特征和特性. 当然,正常思路逆向也是没问题的(例如我们的ttw课程全数据逆向),你就当多了一个针对于该引擎逆向的快捷方式 或则多了一个思路即可. 正常逆向+引擎分析,使逆向结果全面且快速.

任鸟飞2217777779的博客 1万+

TCP、UDP数据包大小的限制

1、概述 首先要看TCP/IP协议,涉及到四层:链路层,网络层,传输层,应用层。    其中以太网(Ethernet)的数据帧在链路层    IP包在网络层    TCP或UDP包在传输层    TCP或UDP中的数据(Data)在应用层    它们的关系是 数据帧{IP包{TCP或UDP包{Data}}}    不同的协议层对数据包有不同的称谓,在传输层叫做段(se

草上爬的博客 12万+

WSL 2 部署 Rocky Linux 9:从零到生产环境配置指南(2025版)

本文详细介绍了如何在WSL 2上部署Rocky Linux 9,从环境准备到生产环境配置的全流程指南。通过优化安装流程和系统配置,帮助开发者和运维工程师在Windows环境下高效运行企业级Linux系统,特别适合需要本地开发但部署到RHEL系服务器的项目。

weixin_28455801的博客 479

电磁波函数复数表示法:为什么物理学家偏爱e^(ikz)而非cos(kr-wt)?

本文深入解析了电磁波函数复数表示法(如e^(ikz))相较于传统余弦形式的巨大优势。通过欧拉公式,复数形式将复杂的三角运算转化为简洁的指数运算,在微分、积分、线性叠加及处理相位时展现出极高的计算效率,是物理学家和工程师分析波动现象的核心工具。

weixin_29094539的博客 499

【NIO 系列】——之 TCP 探秘:从阻塞困局到高并发内核

本文深入剖析Java NIO的核心机制与实战应用。首先对比BIO的线程模型瓶颈,揭示NIO通过Selector实现单线程处理多连接的原理。重点解析NIO三大组件:Channel(双向通信)、Buffer(高效数据容器)和Selector(事件驱动核心)。通过完整Echo服务器实现,展示非阻塞编程模式,并指出常见陷阱如粘包处理、OP_WRITE误用等。文章还探讨性能优化方向,包括内核参数调优、零拷贝技术,以及Reactor模型的演进。最后分析Netty对NIO的封装优化和虚拟线程带来的新可能,强调NIO在低延

油墨香^-^的博客 818

llama.cpp部署大模型

llama.cpp如何部署大模型

Eddy的博客 983

NIO的总结,NIO与IO的区别,NIO的优势,带你了解NIO

这里写自定义目录标题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入 欢迎使用Ma...

u011770875的博客 2763

S32K1XX调试--快速定位HardFault

1、背景 程序运行,发现程序跑飞到HardFault,但不清楚为什么会跑到HardFault中断处理函数去。 2、分析 要想知道为什么会跑到HardFault_Handler中去,就很有必要了解一下,程序上一条执行的是那条命令。 根据汇编指令可以定位上条指令,但如果对汇编指令不是很了解的话,那就很头疼了 根据单步运行也能实现定位,但如果程序量很大,又很杂,可能花费的时间就比较久些。 3、问题查找 提供一种不需要懂汇编指令的查找方法,方法如下: 在中断处理函数中插入以下代码,以及另外定义

ping_devil的博客 4020

Unreal从入门到精通之如何绘制用于VR的3DUI交互的手柄射线

之前我写过一篇文章《Unreal5从入门到精通之如何在VR中使用3DUI》,其中讲到使用WidgetComponent和3DUI进行交互。然而,这种方法存在一个问题:为了让射线可视化,我们需要勾选“调试/显示调试”,这样才能在手柄上看到代表其指向的一条红色射线。但最关键的问题是,这个显示调试信息的功能只属于Debug调试模式,也就是说,一旦将项目正式打包发布,这条射线辅助线就没有了。如下图所示:我就觉得Unreal官方真的是有点过分了,这不应该是最基本的功能么?难道我们VR要在Debug模式下发布?

TxNet 1614

NIO系列4:TCP服务数据读写

注:本文适合对象需对java NIO API的使用及异步事件模型(Reactor模式)有一定程度的了解,主要讲述使用java原生NIO实现一个TCP服务的过程及细节设计。 上文讲到当客户端完成与服务端的连接建立后,为其SocketChannel封装了一个session对象代表这个连接,并交给processor处理。 processor的内部有3个重要的队列,分别存放新创建的sessio

瞬息之间 3562

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

探秘Java NIO TCP代理:高性能网络编程的利器

探秘Java NIO TCP代理:高性能网络编程的利器 在现代软件开发的浩瀚星空中,高效、稳定的网络通信是连接服务的关键。今天,我们聚焦一款名为java-nio-tcp-proxy的开源项目,它如一颗璀璨的星辰,为那些寻求优化网络传输效率和处理能力的开发者们提供了无限可能。 项目介绍 java-nio-tcp-proxy是一个基于Java Non-Blocking I/O (NIO)技术实现的TC...

gitblog_00795的博客 1009

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

【面试心经】——蔚来汽车Linux 岗位开发 02

第四次挥手:客户端收到从服务器端发出的TCP报文,确认了服务器端已做好释放连接的准备,于是再次向服务端发送报文表示接收到服务端准备好释放连接的信号,并进入TIME-WAIT阶段等待2MSL ( 最大报文生存时间) 后再断开连接,服务端收到最终确认报文后立即断开连接,双方断开TCP连接。第三次挥手:服务端自从发出ACK确认报文之后,经过了关闭等待阶段,做好了释放服务器端到客户端方向上的连接准备,再次向客户端发出一段TCP报文表示已经准备好释放连接了(没有数据需要传输给客户端了),然后进入最后确认状态。

点滴路程 1782

nio tcp 释放_NIO系列4:TCP服务数据读写

注:本文适合对象需对java NIO API的使用及异步事件模型(Reactor模式)有一定程度的了解,主要讲述使用java原生NIO实现一个TCP服务的过程及细节设计。上文讲到当客户端完成与服务端的连接建立后,为其SocketChannel封装了一个session对象代表这个连接,并交给processor处理。processor的内部有3个重要的队列,分别存放新创建的session、需要写数据的...

weixin_39854730的博客 151

NIO实现TCP网络通信

NIO实现TCP网络通信 传统socket采用的是阻塞IO模式来实现的Socket通信,这里的阻塞实际上就是程序和内核交互时的模式,在NIO中可以利用NIO的特性实现非阻塞形式的Socket通信 1. 实现步骤 实现服务端的端口监听 实现服务端获取客户端连接并注册到Selector中 实现消息解析 实现客户端代码并测试 2. 服务端实现 2.1 实现服务端的端口监听 public class MyServer { private ServerSocketChannel serverSock

sui_feng_piao_guo的博客 3635

深入了解NIO底层原理

Redis 为何能支持高并发? Redis底层采用NIO中的多路IO复用的机制,很好地支持高并发,并且能实现线程安全。 Redis官方没有windows版本,只有Linux版本。 NIO在不同的操作系统上实现的方式有所不同,在Windows操作系统使用select实现轮训,而且还存在空轮训的情况,效率非常低。时间复杂度是为O(n)。其次默认对轮训的数据有一定限制,所以难于支持上万的TCP连接。 在Linux操作系统采用epoll实现事件驱动回调,不会存在空轮训的情况,只对活跃的socket连接实现主动回调,

陈皮的JavaLib 2658
上一篇: TCP 三次握手原理,你真的理解吗?
下一篇: 正常TCP建连接三次握手过程
王树民
博客等级 码龄10年 912粉丝 560原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值