UDP-阻塞与非阻塞

基于UDP的非阻塞通信 基于UDP的非阻塞通信 如果使用UDP进行阻塞通信,则会在receive()时阻塞(在没有报文到达时)。 如果使用非阻塞通信,就需要“知道”什么时候调用receive(),与基于TCP的非阻塞通信相同,需要一个selector来监听管道的“事件”。当有报文到达时,事件触发。 通过selector,在事件触发时调用receive()接收报文即可。 通信流程 1. 创建DatagramChannel DatagramChannel datagramChannel = DatagramChannel.open() 阅读详情
AI摘要

本文围绕UDP展开,介绍了其阻塞与非阻塞模式。阻塞模式下,未接收到数据接收函数不运行,CPU占用率低;非阻塞模式则相反。还阐述了数据来源与操作系统进程、内存及缓冲区的关系,以及发送函数的阻塞和非阻塞情况,最后说明了UDP数据报面向非连接、传输效率高但会丢包乱序的特点。

UDP-阻塞与非阻塞设置socket非阻塞阻塞查看数据从哪儿来操作系统相关获取缓冲区的大小发送函数的阻塞和非阻塞UDP数据报的特点

UDP-阻塞与非阻塞

基于UDP

//阻塞: // 没有接受到数据,就不运行接收函数。 // 像这类必须要发生事件才能继续往下进行的函数称为阻塞函数 // 例:老王烧水,水壶没开,就一直等,直到水壶开才去做别的。 // // 非阻塞函数: // 例:老王烧水,水壶没开,老王去做别的,每隔一段时间回来看水壶开没开 // // // 实质: // socket是阻塞的,和函数没有关系。 // 关系socket使用的方式,是阻塞的还是非阻塞的。 // socket默认是阻塞的。

设置socket非阻塞

语法

int WSAAPI ioctlsocket(
   [in]      SOCKET s,
   [in]      long   cmd,
   [in, out] u_long *argp
 );

参数

[in] s

标识套接字的描述符。

[in] cmd

要 对套接字执行的命令。

[in, out] argp

指向 cmd 参数的指针。

返回值

成功完成后, ioctlsocket 将返回零。 否则,将返回值 SOCKET_ERROR,并且可以通过调用 WSAGetLastError 检索特定的错误代码。

//-------------------------

// Set the socket I/O mode: In this case FIONBIO

// enables or disables the blocking mode for the

// socket based on the numerical value of iMode.

// If iMode = 0, blocking is enabled;

// If iMode != 0, non-blocking mode is enabled.

0阻塞,1 非阻塞

实例
     //-------------------------
 // Set the socket I/O mode: In this case FIONBIO
 // enables or disables the blocking mode for the 
 // socket based on the numerical value of iMode.
 // If iMode = 0, blocking is enabled; 
 // If iMode != 0, non-blocking mode is enabled.
 
 iResult = ioctlsocket(m_socket, FIONBIO, &iMode);
 if (iResult != NO_ERROR)
   printf("ioctlsocket failed with error: %ld\n", iResult);

代码

//设置socket是非阻塞模式
     u_long iMode = 1;
     ioctlsocket(sock,FIONBIO,&iMode)

运行结果

修改:

更改报错条件

断点调试结果

没有收到数据也会反复运行recv函数。

阻塞

停在recv函数也就是79的位置,不会继续往下运行。

查看

ctrl+shift+esc=打开任务管理器

非阻塞模式

阻塞模式

非阻塞模式会比阻塞模式占用更多的CPU。

特点

非阻塞

  1. 等待的事情发生不一定第一时间知道。
  2. CPU 的占用率高。

阻塞

  1. 等待的事情发生第一时间知道。
  2. 没有接收到数据时任务挂起,CPU占用率低。

数据从哪儿来

操作系统相关

  • 进程与内存

操作系统会给每个进程分配4G的虚拟内存。实际的分配内存不到4G。操作系统会实时分配内存给进程,一个进程的最大大小为4G。

  • 虚拟内存
  1. 物理地址通过映射为虚拟地址。
  2. 一个进程的实际空间最大4G,4G并不是实际的大小。
  • 虚拟内存的分配

内核空间:0-2G

是所有进程公有的。

socket :创建时操作系统会给每一个socket创建两个缓冲区。

当数据到达操作系统,会根据对应的端口号发往对应的socket,写入其对应的接收缓冲区里。

接收缓冲区:接收对方数据

发送缓冲区:缓存待发送数据

当要发送数据的时候,操作系统会将要发送的数据写入对应的socket的发送缓冲区。

用户空间:2G-4G

是一个进程自己私有的。

当程序调用recvfrom 函数,数据被拷贝进recvBuf。

recvBuf:将数据从内核空间的接收缓冲区拷贝到recvBuf里。

实际发送,操作系统通过调度,使用空闲网卡发送数据。

sendBuf:将数据从内核空间的发送缓冲区拷贝到sendBuf。

  • 总体描述
    • 操作系统给每个进程分配虚拟存储空间在内存。最大为4G。
    • 其中2G为内核空间。内核空间为公共的,所有进程可以访问。一个进程每创建一个socket,操作系统就会为其创建一个接收缓冲区,和一个发送缓冲区。
    • 虚拟内存的另外2G是内存空间。内存空间是私有的,只有该进程可以访问。用于存放函数调用时需要使用的数据如recvBuf。
    • 数据发送时操作系统会对应数据包中的端口号找到对应的socket,将该数据存入该socket的发送缓冲区。
    • 当操作系统调用函数recvfrom时,会将数据从内核空间的接收缓冲区拷贝到内存空间。
    • 发送数据需要操作系统调度。只要发送缓冲区有数据,就会使用空闲网卡发送到对应的端口。

获取缓冲区的大小

getsockopt

语法

int WSAAPI getsockopt(
   [in]      SOCKET s,
   [in]      int    level,
   [in]      int    optname,
   [out]     char   *optval,
   [in, out] int    *optlen
 );

参数

[in] s

标识套接字的描述符。

[in] level

定义选项的级别。 示例: SOL_SOCKET。

[in] optname

要为其检索值的套接字选项。 示例: SO_ACCEPTCONN。 optname 值必须是在指定级别内定义的套接字选项,否则行为未定义。

[out] optval

一个指向缓冲区的指针,在该缓冲区中,将返回所请求的选项的值。

[in, out] optlen

指向 optval 缓冲区的大小(以字节为单位)的指针。

返回值

如果未发生错误, 则 getsockopt 返回零。 否则,将返回值 SOCKET_ERROR,并且可以通过调用 WSAGetLastError 来检索特定的错误代码。

注解

如果从未使用 setsockopt 设置选项,则 getsockopt 将返回该选项的默认值。

getsockopt 支持以下选项。 “类型”列标识 optval 寻址的数据类型。

有关套接字选项的详细信息,请参阅 套接字选项。

当 level 参数设置为 SOL_SOCKET 时,optname 参数的值表有效。

值类型含义
SO_ACCEPTCONNBOOL套接字正在侦听。
SO_BROADCASTBOOL套接字配置为传输和接收广播消息。
SO_BSP_STATECSADDR_INFO返回本地地址、本地端口、远程地址、远程端口、套接字类型和套接字使用的协议。
SO_CONDITIONAL_ACCEPTBOOL从上一次调用 setsockopt
或系统默认值返回当前套接字状态。
SO_CONNECT_TIMEDWORD返回已连接套接字的秒数。 此套接字选项仅适用于面向连接的协议。
SO_DEBUGBOOL已启用调试。
SO_DONTLINGERBOOL如果 为 TRUE,则禁用SO_LINGER选项。
SO_DONTROUTEBOOL路由功能被禁用。 此设置成功,但在AF_INET套接字上将被忽略;使用 WSAENOPROTOOPT
AF_INET6套接字失败。 ATM 套接字不支持此选项。
SO_ERRORint检索错误状态并清除。
SO_EXCLUSIVEADDRUSEBOOL阻止任何其他套接字绑定到同一地址和端口。 在调用 绑定
函数之前,必须设置此选项。
SO_GROUP_IDGROUP保留。
SO_GROUP_PRIORITYint保留。
SO_KEEPALIVEBOOL正在发送“保持连接”。 ATM 套接字不支持。
SO_LINGERLINGER
结构
返回当前的逗留选项。
SO_MAX_MSG_SIZEunsigned int面向消息的套接字类型的消息的最大大小 (例如,SOCK_DGRAM) 。 对于面向流的套接字没有意义。
SO_OOBINLINEBOOL正在正常数据流中接收 OOB 数据。 (有关本主题的讨论,请参阅 Windows 套接字 1.1 阻止例程和 EINPROGRESS
部分。)
SO_PORT_SCALABILITYBOOL通过为本地计算机上的不同本地地址端口对多次分配通配符端口,允许最大化端口分配,从而为套接字启用本地端口可伸缩性。
SO_PROTOCOL_INFOWSAPROTOCOL_INFO绑定到此套接字的协议的协议信息的说明。
SO_RCVBUFint为接收保留的每个套接字的总缓冲区空间。 这与SO_MAX_MSG_SIZE无关,也不一定对应于 TCP 接收窗口的大小。
SO_REUSEADDRBOOL可以将套接字绑定到已在使用中的地址。 不适用于 ATM 插座。
SO_SNDBUFint为发送保留的每个套接字缓冲区总空间。 这与SO_MAX_MSG_SIZE无关,也不一定对应于 TCP 发送窗口的大小。
SO_TYPEint套接字的类型 (例如,SOCK_STREAM) 。
PVD_CONFIG服务提供程序依赖与 套接字关联的服务提供程序中的不透明数据结构对象。 此对象存储服务提供程序的当前配置信息。 此数据结构的确切格式特定于服务提供程序。
  • level的其它选项
  • 水平 = IPPROTO_TCP

代码

//获取缓冲区大小
	int bufLen;
	int optval;
	int optvalLen = sizeof(optval);
	err=getsockopt(sock,SOL_SOCKET, SO_RCVBUF,(char*)&optval,&optvalLen);
	if (SOCKET_ERROR == err) {
		cout << "getsockopt  recv error" << GetLastError() << endl;
		return 1;
	}
	else {
		cout << optval << " getsockopt recv  success" << endl;
	}
	int bufLenSend;
	int optvalSend;
	int optvalLenSend = sizeof(optvalSend);
	err = getsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char*)&optvalSend, &optvalLenSend);
	if (SOCKET_ERROR == err) {
		cout << "getsockopt send  error" << GetLastError() << endl;
		return 1;
	}
	else {
		cout << optvalSend << " getsockopt send success" << endl;
	}

运行结果

结果分析

65536B=64KB

发送缓冲区的大小是64KB,发送的数据大小尽量不要超过超过64KB,以避免数据丢失。

第一次往发送缓冲区拷贝30KB的数据,网卡忙碌,数据缓存没有发出去,下一次拷贝数据时就只有30KB的空间。

也就是发送缓冲区可能缓存不止一次需要发送的数据。

  • 如何判断数据的大小
  • 函数sendto的返回值是实际拷贝的数据的大小。
  • 如果sendNum的大小等于sizeof(sendBuf)要发送的数据的大小。那么数据被完全拷贝发送。
  • 如果sendNum<sizeof(sendBuf),那么需要再写一个发送函数对数据进行拷贝发送。
  • 客户端不需要这么麻烦,一个网卡只为一端服务。

发送函数的阻塞和非阻塞

当发送缓冲区的空间不足够大的时候,才会阻塞。

阻塞发送:等到空间足够大的时候,再往缓冲区拷贝数据。

非阻塞发送:当空间不够大的时候,非阻塞发送就是有多少空间拷贝多少数据,剩余的数据程序自己处理。丢弃,或者人工处理。

UDP数据报的特点

  1. 面向非连接,可以接收任意人发来的数据。可以是1对1,也可以是1对多。(创建既发送)
  2. 通讯方式是数据报文的通讯方式,(多个)数据报之间不会粘连,(单个)数据报不可拆分。
  3. 传输效率高。(对比TCP)
  4. 会产生丢包和乱序。(丢包:在数据传输的路上,也就是路由器转发的时候丢失)(迷路的数据会在路由器中不断转发,一段时间后就会被丢弃。)(乱序:后发送的数据包比先发送的数据包更快到达目的端口。)
  5. UDP没有丢包处理,但同时它的传输效率高。
C++ Windows非阻塞UDP通信源码 UDP通信中,recvfrom或recv等函数默认都是阻塞方式进行的,即如果没有收到消息,那么程序会一直卡在recv()这个函数这里,使得该线程不能进行后续的操作。但有时候我们需要该线程在有UDP数据发送过来的时候才进行数据接收,而在其他时间该线程还有别的任务进行处理,那么我们就需要将Sokcet设置为非阻塞通信的方式。非阻塞通信中,需要用到select()函数,select函数用于在非阻塞中,当一 阅读详情

相关推荐

Linux UDP socket 设置为的非阻塞模式与阻塞模式区别

主要介绍了Linux UDP socket 设置为的非阻塞模式与阻塞模式区别的相关资料,需要的朋友可以参考下

TCP、UDP的阻塞和非阻塞模式

前言 socket在默认情况下是阻塞状态的,这就使得发送和接受都处于阻塞状态; TCP协议下发送选用send,UDP协议下,发送选用sendto. TCP协议下接收选用recv,UDP协议下,接收选用recvfrom. 一、阻塞模式&&send 假设发送缓冲区大小为4096KB,其中已经使用4000KB空间,剩余96KB空间;现在又有200KB的数据需要发送,则只能先将96KB的数据放入发送缓冲区但不发送(阻塞),直到缓冲区空出空间足够放入剩余104KB,再send操作将这200子节发送

lzg_na的博客 9452

鱼眼相机去畸变(图像拉直/展开/矫正)算法及实战总结

1、算法说明经纬度矫正法, 可以把鱼眼图想象成半个地球, 然后将地球展开成地图,经纬度矫正法主要是利用几何原理, 对图像进行展开矫正。经过P点的入射光线没有透镜的话,本应交于相机成像平面的e点。然而,经过鱼眼相机的折射,光线会交于相机成像平面的d点,就产生了畸变,因此畸变图像整体上呈现出像素朝图像中心点聚集的态势。而去畸变,就是将折射到d点的点,重新映射回到e点,因此去畸变之后的图像与原始的鱼眼图像相比,仿佛是把向心聚集的像素又重新向四周铺展开来。AVM环视系统——鱼眼相机去畸变算法 - 知乎。

大胡子大叔的专栏 2万+

5种IO模型、阻塞IO和非阻塞IO、同步IO和异步IO

5种IO模型、阻塞IO和非阻塞IO、同步IO和异步IO       看了一些文章,发现有很多不同的理解,可能是因为大家入切的角度、环境不一样。所以,我们先说明基本的IO操作及环境。本文是在《UNIX网络编程 卷1:套接字联网API》6.2节"I/O 模型 "的基础上,即UNIX/LINUX环境下的网络 IO环境下的理解,它里面给出的例子是读取(接收)网络UDP数据。下面简单写写自己对这些IO模型的...

yinni11的博客 487

Colab虚拟环境配置全攻略:从安装到实战应用

本文详细介绍了在Google Colab中配置Python虚拟环境的完整流程与实战技巧。通过安装Anaconda、创建独立环境、解决常见错误及结合深度学习项目应用,帮助用户有效管理依赖、避免冲突,并利用环境持久化策略提升在Colab中的开发效率与项目可复现性。

weixin_29204121的博客 339

ST7102驱动移植与调试实战

本文详细介绍了在君正T40平台上移植和调试ST7102 LCD驱动芯片的实战经验。内容涵盖硬件接口配置、时序参数调整、寄存器初始化序列编写及常见问题解决,重点解析了ST7102单芯片集成显示与触控功能的特性,为嵌入式设备显示驱动开发提供实用指南。

k6l7m8n9的博客 1410

UDP服务recvfrom函数设置非阻塞

基本概念: 方法一:通过fcntl函数将套接字设置为非阻塞模式。 方法二:通过套接字选项SO_RECVTIMEO设置超时。 方法一源码,编译:g++ udp_server.cpp -o server #include #include #include #include #include #include #include #include #include #i

daiyudong2020的博客 4万+

frp内网穿透(socks隧道)

在实验过程中还是遇到了挺多的问题,但好在大多都解决了。不过还是遗留了一些不懂的问题,等以后再慢慢研究了。最后,以上仅为个人的拙见,如何有不对的地方,欢迎各位师傅指正与补充,有兴趣的师傅可以一起交流学习。

2301_76227305的博客 1万+

如何将UDP的recvfrom函数设置为非阻塞或阻塞超时

本文先介绍我查看了的2篇文章,然后介绍linux 和windows 下的非阻塞设置。最后是非阻塞情况下接收情况的判断。 2篇博文 其实UDP的非阻塞也可以理解成和TCP是一样的,都是通过socket的属性去做。 方法一:通过fcntl函数将套接字设置为非阻塞模式。 方法二:通过套接字选项SO_RECVTIMEO设置超时。 https://blog.youkuaiyun.com/daiyudong202...

qq_36570733的博客 1万+

无需UMAT:基于Abaqus内置模型实现形状记忆聚合物结构的热-力耦合仿真

本文详细介绍了如何利用Abaqus内置模型实现形状记忆聚合物(SMP)的热-力耦合仿真,无需编写复杂的UMAT子程序。通过广义Maxwell模型和Neo-Hookean模型的组合应用,结合完整的热-力耦合分析流程,帮助工程师高效模拟SMP的形状记忆行为。文章还提供了工程应用案例和常见问题解决方案,为相关领域的研究和设计提供实用指导。

weixin_34005090的博客 116

HttpClient跳过HTTPS证书验证的3种实战方法(含完整代码示例)

本文详细介绍了HttpClient跳过HTTPS证书验证的3种实战方法,包括自定义TrustManager、SSLContext配置和HttpClientBuilder高级定制,并提供完整代码示例。这些方法适用于开发和测试环境,帮助开发者快速解决自签名证书或未认证证书导致的HTTPS请求失败问题,但需注意生产环境的安全风险。

weixin_29213655的博客 530

UDP 不阻塞的原因

Android UDP 开发中,在接收数据的时候,有的手机无法阻塞??? 原因: 不要在主线程中写相关UDP代码,将代码写到新建线程run函数中。 问题解决代码示例: new Thread(){ public void run() { // UDP服务器监听的端口 Integer port = 8888; // 接收的字节大小,客户端发送

王月星 4262

【腾讯小龙虾WorkBuddy专栏01】初识WorkBuddy!定位、核心优势、功能界面全解析

【腾讯小龙虾WorkBuddy专栏01】初识WorkBuddy!定位、核心优势、功能界面全解析

AI人人懂 3822

UDP/IP 阻塞模式与非阻塞模式

package concurrentTest; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.net.SocketException; /** * UDP/IP阻塞模式 *

Scott的专栏 7722

Nvidia Jetson 编解码开发(3)解决H265解码报错“PPS id out of range”

基于之前的开发程序通过Jetson Xavier NX 硬编码的H265发出后,上位机断点播放发出来的H265码流,会报“PPS id out of range” 错误。

jzwjzw19900922的博客 3810

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

Linux下UDP的连接程序示例(阻塞、非阻塞)

由于前面已有介绍,关于函数就不介绍了 /*server.c*/ #include #include #include #include #include #include #include #include #include #include #define SIZE 512 int sock_bind(int lisfd, int port) { struct soc

CodeHeng的专栏 7872

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

TCP和UDP阻塞和非阻塞之间的区别

我在网络上看到某些人说,阻塞就是将数据真正发送给对方,并且阻塞是发生在需要把前面的所有数据全部发送出去,然后再发送本次的,而非阻塞则是拷贝到发送缓冲区。我不得不说,上面的这种说法是错误的。man 一下 send,发现man里有描述容易误导,send() shall fail.应该是需要自己判断的,会返回实际发送成功的字节,想全部成功发送,需要自己实现一遍阻塞循环发送的逻辑,当多端口*大包发送的时候,可以非阻塞拆包发送(循环每个端口send一次小包,避免单个端口阻塞很久),效果会比阻塞的好很多。

自主无人机 PX4 ROS SLAM 路径规划 MVS等技术分享 808

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

UDP socket 设置为的非阻塞模式

非阻塞写的情况下,是采用可以写多少就写多少的策略.与读不一样的地方在于,有多少读多少是由网络发送的那一端是否有数据传输到为标准,但是对于可以写多少是由本地的网络堵塞情况为标准的,在网络阻塞严重的时候,网络层没有足够的内存来进行写操作,这时候就会出现写不成功的情况,阻塞情况下会尽可能(有可能被中断)等待到数据全部发送完毕, 对于非阻塞的情况就是一次写多少算多少,没有中断的情况下也还是会出现write 到一部分的情况.对于一个TCP套接口,内核将从应用进程的缓冲区到该套接口的发送缓冲区拷贝数据。

qq_51994914的博客 4295

Linux下udp程序怎么运行,Linux下UDP的连接程序示例(阻塞、非阻塞)

由于前面已有介绍,关于函数就不介绍了/*server.c_非阻塞式*/#include #include #include #include #include #include #include #include #include #include #include #include #define SIZE 512int sock_bind(int lisfd, int port){struct...

weixin_32136817的博客 519

java非阻塞通信udp,有关UDP非阻塞recvfrom超时设置的有关问题

有关UDP非阻塞recvfrom超时设置的问题本帖最后由 lingducool 于 2013-05-21 21:04:20 编辑我现在想编这么一个程序,向目标端口发送UDP的一个包后,用recvfrom等待接受回应,等待5秒后未接到回应就继续向下执行。我的思路是设置为非阻塞式套接字,然后设置超时5秒,但是这样我没有成功,代码如下:#include#include#include#pragma...

weixin_31443757的博客 862

python udp recvfrom阻塞吗_python – 使用非阻塞udp读取时缺少消息

在两个主机之间的udp中使用非阻塞读取时,我遇到了丢失消息的问题.发件人在linux上,读者在winxp上.python中的这个例子显示了这个问题.以下是用于显示问题的三个脚本.send.py:import socket, syss = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)host = sys.argv[1]s.sendto('A'*10,...

weixin_39757212的博客 2891

java udp 非阻塞_Matlab GUI中的非阻塞UDP接收器

当然,除了 BytesAvailableFcn 之外,matlab还有datagramreceivedfcn在新的dagatrams上调用你的自定义函数,这是非阻塞而fread / fscanf阻塞(暂时) .关于matlab中的回调,请阅读events and cbsCompillable standalone可能如下所示:%% standalone main%{see docs/*%}func...

weixin_39607090的博客 353

java udp 非阻塞,非阻塞UDP I / O与阻止Java中的UDP I / O.

Non-blocking TCP/IP SocketChannels and Selector in NIO help me to handle many TCP/IP connections with small number of threads. But how about UDP DatagramChannels? (I must admit that I'm not very fam...

weixin_32520095的博客 284

php udp 非阻塞,使用非阻塞udp读取时丢失消息

当在两个主机之间使用非阻塞的udp读取时,我有丢失消息的问题。发送者在linux上,读取器在winxp上。python中的这个例子显示了这个问题。这里有三个脚本用于显示问题。发送.py:import socket, syss = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)host = sys.argv[1]s.sendto('A'*10, (...

weixin_39892800的博客 266

Linux Socket网络编程UDP、TCP 阻塞与非阻塞 断线重连机制

一·、UDP协议及其工作原理 (10条消息) UDP.01.基础知识+基础模型_老毛的博客-优快云博客 (10条消息) Socket原理讲解_Tony-jiang的博客-优快云博客_socket 二、UDP在Linux下的编程方式 2.1 参考链接: (10条消息) UDP的编程流程_liqiao_418的博客-优快云博客_udp流程 (10条消息) UDP编程步骤_judgejames的博客-优快云博客_udp过程 2.2 编程流程 服务端: //1.创建套接字 #inclu

qq_42475191的博客 7485
下一篇: UDP_Server
小姨火辣辣
博客等级 码龄4年 38粉丝 5原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值