学习笔记之SOCKET网络编程之二

杰理蓝牙SPP用户接口详细文档 本文档详细介绍了基于JL701n芯片的蓝牙SPP用户接口实现。主要内容包括:1) 文件结构分析,包含必要的头文件和调试配置;2) 核心数据结构,如全局变量和TWS功能ID定义;3) 五大功能模块实现:数据发送、状态管理、数据接收、TWS支持和初始化清理;4) API接口说明,包括公共接口函数和回调函数;5) 使用教程,涵盖基本流程和高级应用示例。该接口支持虚拟串口连接,实现蓝牙设备间数据传输,特别针对TWS场景进行了优化,提供连接状态管理、数据收发等功能。文档还包含错误处理、重试机制等实用建议,适合蓝牙SP 阅读详情
1.sendto()和recvfrom()函数
Sendto()和recvfrom()函数用于在无连接的数据报套接字方式下进行数据发送和接收.

sendto()函数
定义:int sendto(int s,void *msg,int len,unsigned int flags,struct sockaddr *to, int tolen);
在发送数据时.由于本地端并没有与远程机器建立一个连接.所以在用sendto()发送数据时我们要告诉它把数据发送到哪里?也就是告诉sendto()发送数据的目的地.
所以它比send()函数多了两个参数.
参数 "struct sockaddr* to"用来告诉它发送数据目的地.包括目标机器的IP和端口等信息.
参数 "int tolen"是struct sockaddr结构的大小.
除此之外其它的参数与send()函数完全相同.
函数成功返回实际发送数据的长度.失败返回-1.

recvfrom()函数
定义:int recvfrom(int s,void *buf,int len,unsigned int flags,sockaddr*from,int *fromlen);
因为是利用数据报套接字传送的数据.所以并没有连接.所以recvfrom()在收到数据后需要知道数据到底是谁发来的?在这里称为"源".所以它比recv()函数多了两个参数.
参数from用来记录源机器的地址信息.包括IP地址和端口等信息.
参数fromlen同样是struct sockaddr结构的大小.
其它参数与recv()函数完全相同.
函数成功时返回实际收到的数据长度.失败返回-1.

2.套接字的关闭.
当我们完成通讯后我们需要把套接字关闭.从而释放资源.
关闭套接字的操作通过调用close()函数来实现.
不管是有连接的流式套接字还是没有连接的数据包式的套接字.只要任何一端调用了close()函数关闭了套接字.都将无法再进行通讯.
另外还有一个函数就是shutdown().它允许你将一定方向上的通讯关闭.当然也可双向通讯都关闭.
也就是说shutdown()函数可以让某一端只接收数据.或者只发送数据.
定义:int shutdown(int s,int how);
参数s是我们将要操作的套接字.
参数how是具体的操作方式.
A.为0时表示不允许接收数据
B.为1时表示不允许发送数据
C.为2时表示不允许接收和发送数据(双向通讯都将关闭,与调用close()函数效果一样.)
函数成功时返回0失败时返回-1.

3.其它.
getpeername()函数.
功能:它用来在有连接的流式套接字中获取对方的地址信息.(包括IP地址和端口)
定义:int getpeername(int s, struct sockaddr *addr, int *addrlen);
参数addr用来存放获取的地址信息.
函数失败返回-1.

gethostname()函数.
功能:它用来获取本机的名字.
定义:int gethostname(char *hostname, size_t len);
参数hostname是一个字符类型的缓冲区.它用来保存本机名字
参数len是缓冲区的长度.
函数成功时返回0.失败时返回-1.

gethostbyname(char*name)函数.
功能:返回由参数name指定的机器的地址信息
定义:struct hostent *gethostbyname(const char *name);
参数name可以是用gethostname()函数获取的机器名字
函数成功返回一个指向struct hostent结构体的指针.失败返回NULL

另:此函数返回的是一个struct hostent结构指针.该结构就包含了一个机器的地址信息
该结构的定义:
struct hostent
{
   char *h_name;                   //地址的正式名称
   char **h_aliases;               //空字节 地址的预备名称的指针
   int h_addrtype;                 //地址的类型.WINDOWS中通常为AF_INET
   int h_length;                   //地址的长度.以位来计算(不是以字节来计算)
   char **h_addr_list;             //零字节 主机网络地址指针.(网络字节顺序)
#define h_addr  h_addr_list[0]       //h_addr_list中的第一地址
};


4.关于阻塞与非阻塞.

阻塞.
简单的说阻塞就是当你调用accept(),send()或者是recv()等过程后.程序必须要等待一个返回结果程序才会继续执行下去.在这种情况下,如果你的程序是单线程的.那么你的程序就会完全挂起.

非阻塞.
而非阻塞正好相反.非阻塞套接字是指执行此套接字的网络调用时,不管是否执行成功,都立即返回.

习惯上也称之为同步阻塞和异步非阻塞.


在默认情况下套接字都是阻塞模式的.如果要改变这个设置就要调用fcntl()函数.

fcntl()定义如下:
#include <fcntl.h>
int   fcntl(int  s,int  cmd,  .../* int arg */);
参数s是我们将要设置的套接字.
参数cmd有多种形式.在这里一般设置为F_SETFL.
第三个参数总是一个整数.在此处只需要设置成O_NONBLOCK(表示非阻塞模式)

注意:在windows下的socket编程中.是用iooctlsocket()函数来实现fcntl()函数的功能的.
它的定义如下:
int ioctlsocket(int s,long cmd,u_long *argp);
功能:控制套接字的模式.
参数s是将要操作的套接字.
参数cmd是对套接字的操作方式.
参数argp指向cmd命令所带参数的指针.

参数cmd支持下列几种命令:
A.FIONBIO允许或禁止套接字s的非阻塞模式.参数argp指向一个无符号长整型.如果要允许非阻塞模式则将参数argp设成非零.如果要禁止非阻塞模式(也就是阻塞模式)则将参数argp设成零即可.
注:一个套接字进行了WSAAsyncSelect()操作.它是套接字的一种模式,它将套接字自动设置成非阻塞模式.则任何用试图ioctlsocket()来重新设置套接成阻塞模式的操作都将失败.必须先调用WSAAsyncSelect()来禁止WSAAsyncSelect后才可以.关于WSAAsyncSelect()请查阅其它资料.
B.FIONREAD确定套接字s自动读入数据量.参数argp此时用来存放ioctlsocket()的返回值.如果套接字是SOCKET_STREAM类型(即流式套接字)则FIONREAD返回一次在recv()中所接收到的所有数据量.(即数据长度).这通常与套接字中排队的数据总量相同.如果套接字是SOCK_DGRAM类型.则FIONREAD返回套接字上排队的第一个数据报的大小.
还有一些其它的命令.略.

函数调用成功返回0.失败返回-1.

从系统性能上看,用非阻塞的socket效率和性能更高,但是编程更复杂,特别是当你使用事件或者消息的时候,但是,你可以通过多个工作线程管理多个socket连接,效率非常高,不需要每个工作线程只管理一个socket连接. 用阻塞的方式比较简单,但当较多客户端时消耗系统资源太多.
其大概思想是建立一个线程池,当有socket的事件需要处理时,从线程池中取一个线程来执行,执行完,将线程归还到线程池中.
每个socket连接的时间较长,不断的与服务器交互.每个连接的socket并不是每时每刻都在收发数据.收发数据是断断续续的.这种情况就很适合于上面的方法.

简单的讲同步阻塞常用于连接较少流量较大的地方.非阻塞则刚好相反.用于连接较多.流量较小的地方.
如果要采用阻塞模式.并且要同时处理多个连接.就只能运用多线程来处理.

多路同步.
假设有一台服务器.它一边要进行监听是否有连接到来,还要在其它已经完成的连接上接收数据.也就是accept()和recv()两个函数的调用.当你在调用accept()时遇到阻塞该怎么办.前提是你并没有调用
fcntl()函数把套接字设置非阻塞模式.这时你就可以调用select().它让你可以同时监视多个套接字.它可以告诉你.哪个套接字准备读,哪个套接字准写,哪个套接字发生了意外.

select()函数的定义如下:
int select(int nums,fd_set*reads, fd_set*writes,fd_set *excepts,timeval *timeout);

在讲解select()函数之前我们先讲一下fd_set.
它表示一个集合.具体的讲是一个文件描述符的集合.在此例中都把它理解为套接字描述符.
在Unix中一切都是文件.包括输入设备键盘.硬盘上的文件.还有专门用于网络传输的socket(套接字)等等.所以.在这里都把它当作是socket套接字.
那么文件描述符或者是套接字描述符就好比是WINDOWS下面的句柄.

fd_set的定义如下:
struct fd_set
{
        u_int   fd_count;               /* how many are SET? */
        SOCKET  fd_array[FD_SETSIZE];   /* an array of SOCKETs */
};

对这些集合的操作都是通过一些特定的宏来完成的.
    FD_ZERO(fd_set *set)          //清除一个文件描述符集合
      FD_SET(int fd, fd_set *set)   //把fd添加到集合set中
      FD_CLR(int fd, fd_set *set)   //从集合set中移去fd
      FD_ISSET(int fd, fd_set *set) //测试fd是否在集合set中

现在再来说说select()函数,以及它的用法.
该函数的功能就是用来等待套接字(这里只讨论套接字)状态的改变.
参数nums代表最大的套接字描述符加1.
参数reads,writes和excepts是套接字描述符集合,用来回传该套接字描述符的读,写或例外的状况.
参数timeout指向一个timeval结构.它用来设定select等待的时间.可以设置到微秒级.1秒等于1000毫秒.1毫秒等于1000微秒.虽然可以精确到1微秒.但这只是理想的.实际上跟系统还有硬件有关.
timeval结构的定义如下:
struct timeval
{
   int tv_sec;   /* 秒 */
   int tv_usec;  /* 微秒 */
};

当然你可以将参数timeout设置成NULL,那么它将永远不会超时.
成功返回套接字描述状态改变的个数,如果返回0表示在套接字描述符状态改变前已经超过参数timeout设定的时间.当有错误发生时则返回-1.此时参数reads,writes,execepts和timeout的值变得不可预测.
同时有错误发生时,它会设置全局错误变量.常见错误有下面几种.

EBADF 套接字描述符无效或该套接字已关闭
EINTR 此调用被信号所中断
EINVAL 参数n 为负值
ENOMEM 核心内存不足

select()函数的常见用法.

//============
    ......
sockfd = socket(AF_INET, SOCK_STREAM, 0); //获取一个套接字
         ......
fs_set readset; //定义套接字集合,用于查看读状态
FD_ZERO(&readset); //对该集合进行清除操作.
timeval  out; //创建一个timeval结构
out.tv_sec=5; //设定等待秒数为5秒
out.tv_usec=1000*500; //设定等毫秒数为500毫秒
//总的等待时间为5秒+500毫秒.
select(sockfd+1,&readset,NULL,NULL,&out); //select()函数的调用.
if(FD_ISSET(sockfd,readset))//进行判断
    ......
//=============



5.socket编程的最后一个问题
这也是socket编程中的第一个问题.如果你是在windows下面编程的话.

在windows下面进行socket编程我们首先要对socket进行初始化.这时就要用到WSAStartup()函数.
在windows中要调用所有的socket函数之前.我们必须先调用WSAStartup()函数
其定义如下:
int WSAStartup(WORD wVer,WSADATA* lpWSAData);
参数wVer指明可使用的windows socket的版本号.高位字节标明副版本号.低位字字指明主版本号.
参数lpWSAData是指向WSADATA结构的指针.用来接收windows socket实现的细节.
成功时返回0失败返回错误代码.

这里将用MAKEWORD()宏.

MAKEWORD(a,b)它的作用是把a和b组成一个WORD值.
其中第一个参数a是高8位的值.第二个参数b是低8位的值.
我们就是用它来把windows socket的版本号放入WSAStartup()函数的.

例程:
//=====================
WORD sver=MAKEWORD(1,1);//设置socket版本号为1.1
WSADATA wsda;//创建WSADATA结构
if(WSAStartup(sver,&wsda)==0)//调用WSAStartup函数初始化socket
{
    //调用成功.初始化成功
}
//=====================

另外一个函数.它是windows socket编程中的最后一个问题.
WSACleanup()函数.它是终止windows socket的调用.注销windows socket.释放资源.
任何打开的并已建立连接的SOCK_STREAM流式套接字.在调用WSACleanup()时会重置.而已经由close()关闭却仍有要发送而未发送的数据的套接字则不会受影响.该数据仍要发送.
通常.WSACleanup()函数与WSAStartup()函数应成对出现.也就是说对于一个进程的每一次WSAStartup()调用.必须有一个WSACleanup()调用.
但是只有最后一个WSACleanup()调用才会做实际的清除工作.前面的WSACleanup()调用仅仅将windows socket DLL中的内置引用计数递减1.
一般情况下,为了确保WSACleanup()调用了足够的次数.可以在最后用一个循环来不断的调用WSACleanup()函数.直到返回WSANOTINITIALISED为止.
该函数的定义:
int WSACleanup ( void );
函数成功返回0.失败返回-1.同时会设置全局错误变量.
常见的几种错误代码.
A.WSANOTINITIALISED使用本函数之前没有一次成功的WSAStartup()调用.简单的讲.它就是说.前面已经没有WSAStartup()调用了.在这里可以不需要再调用WSACleanup()函数来释放资源了.
B.WSAEINPROGRESS一个阻塞的windows socket操作正在进行.简单的讲.它就是说你正准备注销的这个套接字中某一个操作(比如recv())遇到了阻塞.


<全文完>


 来自: http://blog.sina.com.cn/s/blog_56ea069101000bxm.html
基于粒子群优化的PID控制在药液流量控制系统中的应用 本文提出了一种基于粒子群优化(PSO)的PID控制算法,用于药液流量控制系统。系统采用C37控制器和Codesys 2.3编程环境实现,通过传感器实时监测流量、压力和车速,并控制水泵占空比和电动球阀开度来精确调节药液流量。硬件配置包括FT-2000流量传感器、PT-3000压力传感器和MV-500电动球阀等。控制算法将PSO与PID结合,使用ITAE指标优化PID参数,在Codesys中实现了包含PSO优化循环、PID控制等功能的程序模块。该系统通过分层控制策略和智能优化算法,提高了药液流量控制的精度和响应 阅读详情

相关推荐

VC中基于TWAIN协议控制扫描仪-----初级版

PS:本人是C++小白一枚,在研究此功能时不知走了多少弯路

a1101000099的专栏 8789

linux send 阻塞方式,关于send和sendto阻塞和非阻塞模式的底层细节

对于sendto,Linux 内核最后会调用udp_sendmsg,大概的调用堆栈是udp_sendmsgsecurity_socket_sendmsg__sock_sendmsgsock_sendmsgsendto在sento里面,会根据socket的模式把一个标志传递给内核:if (sock->file->f_flags & O_NONBLOCK)flags |= MSG_...

weixin_39640543的博客 1960

汇川H5U搭配步进伺服电机使用CANopen通讯控制电机案例

摘要:本文介绍了基于汇川H5U PLC和STM4260B-CANopen-M步进伺服电机的控制系统搭建流程。主要内容包括:硬件准备(PLC、伺服电机、24V电源)、电机参数默认设置(地址1号、1M波特率)、使用AutoShop软件编写程序(配置CANopen参数、导入电机描述文件、设置PDO参数)以及功能块编程(使能控制、速度控制、绝对位置控制等)。通过查阅通讯手册完成各功能块参数配置,最终在主程序中调用功能块实现控制系统开发。该方案适用于需要精确运动控制的工业自动化场景。

m0_46512607的博客 1596

阻塞socket 和非阻塞socket的区别(浅显易懂版)

对于这个问题,我们要先弄清什么是阻塞/非阻塞。阻塞与非阻塞是对一个文件描述符指定的文件或设备的两种工作方式。阻塞的意思是指,当试图对该文件描述符进行读写时,如果当时没有东西可读或者暂时不可写,程序就进入等待状态,直到有东西可读或者可写为止。非阻塞的意思是,当没有东西可读或者不可写时,读写函数就马上返回,而不会等待。现在来理解什么是阻塞socket,什么是非阻塞socket。

qq_56734304的博客 2384

2024年全国大学生信息安全竞赛安徽省赛网络系统建设与运维赛项-网络构建真题

该网络工程方案主要包含基础配置、有线网络、无线网络、出口网络、运维配置和SDN网络六个部分。基础配置包括设备接口设置、SSH服务开启和SNMP功能配置。有线网络部分重点部署VLAN、MSTP、VRRP和OSPF协议,实现网络冗余和负载均衡。无线网络规划了AP点位、信号覆盖和用户接入策略,包括SSID配置、频段优化和安全认证。出口网络配置了NAT转换、VPN隧道和流量审计功能。运维方面搭建了监控平台实时监测设备状态。SDN网络部分通过控制器实现流量管控。整个方案实现了多业务隔离、高可用性网络架构和

weixin_42221934的博客 1174

Jenkins离线安装保姆级教程:从下载.war包到SVN+Maven项目一键部署(附避坑脚本)

本文详细介绍了Jenkins离线安装的全流程,包括.war包下载、SVN+Maven项目配置及自动化部署。特别针对内网环境提供解决方案,涵盖插件管理、开发工具链配置、构建触发器和SSH部署等关键步骤,帮助企业在网络隔离环境下实现高效持续集成。

weixin_30096975的博客 375

Linux 网络编程之 TINY 程序

在tiny程序中从零开始学习web服务程序

df12138的博客 1846

Ubuntu下Charm-Crypto安装

经过一下午的努力终于是把Charm-Crypto给安上了,经过查询资料,大致有三种方案(两坑一可行)。 适用于我的电脑的是Ubuntu 18.04版本。 第一种方案是根据连接https://pypi.org/project/charm-crypto/的教程进行安装,但是该方案的优势在于下载快速,缺陷在于Ubuntu系统仅仅更新到13+版本。 第二种就是网络博客上的介绍,内容与第一种较类似,但是有16+,18+成功的例子,缺点就是bug太多,我大部分时间都耗在了这上边,而且还没有成功。 第三中是github上

Mr.Yi的博客 2284

Socket网络编程学习笔记

Socket网络编程学习笔记    一、IP地址操作类       1、IPAddress类       a、在该类中有一个 Parse()方法,可以把点分的十进制IP表示转化成IPAddress类,方法如下:       IPAddress address = IPAddress.Parse(“192.168.0.1”);        b、IPAddress提供4个只读字段

luyuncsd123的专栏 1715

深入Netflix影片分类数据抓取的Python爬虫实战:反反爬机制绕过与Playwright应用全解析

技术工具用途Playwright控制真实浏览器模拟用户行为开发语言asyncio异步调度浏览器任务pandas数据处理和导出sqlite3本地数据库存储支持随机UA模拟,增强反爬能力为什么选择 Playwright?✅ 支持多浏览器(Chromium、Firefox、WebKit)✅ 原生支持 Python 异步编程✅ 提供截图、滚动模拟、验证码处理等高级功能✅ 反爬能力强,模拟真实用户访问。

2201_76125261的博客 1239

DeFi核心协议代码解析

本文解析了DeFi两大核心协议Uniswap V2和Compound的智能合约架构与关键代码。Uniswap V2采用恒定乘积公式(x*y=k)实现自动做市,核心合约包括Factory、Pair和Router,具备流动性铸造、代币兑换和TWAP预言机功能。Compound借贷协议通过cToken合约管理存款和借款,采用动态利率模型和抵押率机制,包含资金利用率计算、清算触发等核心算法。两协议均采用模块化设计,通过智能合约实现去中心化金融服务的核心逻辑。

闲人编程的博客 935

SOCKET网络编程学习笔记

SOCKET网络编程学习笔记

gghhb12的博客 1262

18年陕西省TI杯电赛无人机赛题视觉部分

更新: 相同任务另外两种不同的视觉方法: https://blog.youkuaiyun.com/qq_41895747/article/details/97613077 https://blog.youkuaiyun.com/qq_41895747/article/details/97614971 任务:识别前方的方框,无人机从方框中飞出去 视觉任务:识别特定方框,返回方框中心坐标 # -*- codin...

沉迷单车的追风少年 1506

java学习笔记————Socket网络编程小总结

**对于网络编程其实就相当于,在生活中人与人之间的交流,提问的一方作为用户端,回答问题的一方作为服务器端** 接下来我就和大家我学习socket网络编程所学到的知识

Belief的博客 497

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

Linux学习笔记——网络编程socket篇

Socket 是一个编程接口 是一种特殊的文件描述符 (everything in Unix is a file) 并不仅限于TCP/IP协议 面向连接 (Transmission Control Protocol - TCP/IP) 无连接 (User Datagram Protocol -UDP 和 Inter-network Packet Exchange - IPX)

m0_64432298的博客 1810

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

网络编程学习笔记一:Socket编程

“一切皆Socket!” 话虽些许夸张,但是事实也是,现在的网络编程几乎都是用的socket。 ——有感于实际编程和开源项目研究。 我们深谙信息交流的价值,那网络中进程之间如何通信,如我们每天打开浏览器浏览网页时,浏览器的进程怎么与web服务器通信的?当你用QQ聊天时,QQ进程怎么与服务器或你好友所在的QQ进程通信?这些都得靠socket?那什么是socket?socket的类型有哪些?还有

程书画的 BLOG 18万+

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

JavaSE学习笔记 基于Socket的TCP网络编程

网络编程1.网络编程的基本知识回顾1.1 C/S与B/S结构1.2 网络编程的三要素解析1.2.1 IP地址1.2.2 端口号1.2.3 网络协议2.Socket通信 前面我们对网络编程的基本知识做了一定的了解,下面将正式进入网络编程之中。 1.网络编程的基本知识回顾 1.1 C/S与B/S结构 应用程序架构分为两种: 1.C/S架构:C/S(Client/Server)即客户端/服务器 2.B/S架构:B/S(Browser/Server)即浏览器/服务器. C/S架构是一种比较早的软件架构,主要用

qq_41537102的博客 342

python学习笔记2:socket网络编程

如何使用socket进行网络编程

mminions的博客 1121

Linux Socket 网络编程学习笔记

Linux Socket 网络编程学习笔记

ouynagda的博客 259

【学习笔记】简单的socket网络编程实例

TCP的三次握手(图片来自百度百科) TCP的四次分手(图片来自百度百科) 单向交互套结字 服务端 /* * Author: xusongqi@live.com * * Created Time: 2014年03月19日 星期三 17时29分14秒 * * FileName: sock_server.c * * Descript

许嵩奇 1563

网络编程学习笔记:Socket编程

一切皆Socket!” 话虽些许夸张,但是事实也是,现在的网络编程几乎都是用的socket。 ——有感于实际编程和开源项目研究。 我们深谙信息交流的价值,那网络中进程之间如何通信,如我们每天打开浏览器浏览网页时,浏览器的进程怎么与web服务器通信的?当你用QQ聊天时,QQ进程怎么与服务器或你好友所在的QQ进程通信?这些都得靠socket?那什么是socket?socket的类型有哪些?还有s...

qq_42920625的博客 256

【Java学习笔记】基于Socket的TCP网络编程和UDP网络编程

一、基于Socket的TCP网络编程 TCP协议的特点: 使用TCP协议前,须先建立TCP连接,形成传输数据通道 传输前,采用“三次握手” 方式,点对点通信, 是可靠的 TCP协议进行通信的两个应用进程:客户端、 服务端。 在连接中可进行大数据量的传输 传输完毕,需释放已建立的连接, 效率低 客户端Socket 客户端程序的工作过程包含以下四个基本的步骤: 创建 Socket: 根据指定服务...

ENKU1的博客 433

Windows Socket网络编程学习笔记一

作者:朱金灿 来源:blog.youkuaiyun.com/clever101 如何理解Windows Socket? 我的理解:Windows Socket相当于Windows平台上两个网络实体开辟的一条通信通道,这条通信通道的实现细节对网络双方是不可见的(呵呵,你就知道它是Windows制造)。通过这条通道,网络双方可以传输各种数据。 你可能...

ladymaidu 82
上一篇: linux下socket connect超时设置
下一篇: 学习笔记之SOCKET网络编程
tinyhare
博客等级 码龄15年 11粉丝 9原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值