网络编程——1、协议基础

1、网络编程基础概念与协议详解 本文详细介绍了网络编程的基础概念与协议,包括客户端、服务器和对等节点的区别,TCP和UDP协议的特点及应用场景,并通过Java代码示例展示了如何实现TCP和UDP通信。同时,还探讨了如何将网络编程与图形用户界面(GUI)结合,以创建更友好的应用程序。 阅读详情

网络编程——1、协议基础,本篇。

网络编程——2、通信基础,点击此处。

网络编程——3、服务器基础,点击此处。

本篇包括网络编程概述、UDP简介、TFTP简介、TCP编程等。

目录

一、tcp/ip协议简介

二、端口

三、IP地址

四、MAC地址

五、socket简介

六、UDP网络通信过程

七、模拟QQ聊天-多线程实现 

八、wireshark抓包工具的使用

九、tftp下载器的使用(tftpd64或tftpd32)

十、UDP广播

十一、TCP服务器、客户端简介及实现

11.1 TCP简介

11.2 TCP和UDP通信模型

11.3 python实现tcp服务器和客户端

一、tcp/ip协议简介

tcp/ip不是两个协议,而是一个协议族,实际为4层,逻辑上可以为7层,如下图所示:

二、端口

为什么使用端口?只有ip地址时只知道发往哪个电脑而不知道发往哪个程序,端口用来辨识要发往的具体程序。

为什么不用PID辨识进程?因为进程是动态的,远端电脑可能不知道本地的pid号。

知名端口:大家都知道的约定好的端口,如80端口为HTTP服务,21端口为FTP服务,范围为0~1023。

动态端口:用户自己定义的端口,范围为1024~65535.

查看端口命令:netstat  -an

注意:在同一个OS中,端口不允许相同,如果某个端口已经被使用了,那么在这个进程释放这个端口之前,其他进程不能使用这个端口。因为端口用来区分一个进程。

三、IP地址

用来逻辑上表示网络上的唯一一台电脑。

注意:一个电脑可以有多个网卡,即多个IP地址!

IP地址分类

其中网络号固定不变,表示位于同一网络中的电脑,主机号为当前网络中的电脑号。

主机号为0时表示网段号,主机号为255时为网关。

D类用于多播(不是广播),例如视频会议,只有一些人可以看到。

E类实验和开发用。

私有ip

用于局域网中,访问公网时不能使用,需要转换为公有ip访问外网。范围如下:

注意

IP地址127.0.0.1~127.255.255.255用于回路测试,即测试当前电脑tcp/ip协议能不能用,例如ping 127.0.0.1,即使拔掉网线也能ping得通。

四、MAC地址

网卡的序列号,形如XX:XX:XX:XX:XX:XX,六组十六进制数,前三组表示厂商序列号,后三组表示网卡序列号。

五、socket简介

socket:通过网络使进程间通信。

注意:一个进程可以有多个socket!

python测试程序如下:

端口绑定(只能绑定自己的端口!)

上面程序每次运行时操作系统为它分配的端口不一样,这导致了远端电脑不知道每次运行的端口,不能发送信息到本地。

python程序如下:

注意:bindAddr中第一个参数为空,因为该参数表示本地IP地址,但本地可能有多个IP,空表示任意ip都进行绑定。

六、UDP网络通信过程

应用层填写需要发送的数据;传输层加上端口号等;网络层加上目的ip等;链路层加上目的mac等;如下图:

七、模拟QQ聊天-多线程实现 

全双工实现QQ聊天,代码如下:

from threading import Thread
from socket import *

#1. 收数据,然后打印
def recvData():
    while True:
        recvInfo = udpSocket.recvfrom(1024)
        print(">>%s:%s"%(str(recvInfo[1]), recvInfo[0]))

#2. 检测键盘,发数据
def sendData():
    while True:
        sendInfo = input("<<")
        udpSocket.sendto(sendInfo.encode("gb2312"), (destIp, destPort))

udpSocket = None
destIp = ""
destPort = 0

def main():
    
    global udpSocket
    global destIp
    global destPort 

    destIp = input("对方的ip:")
    destPort = int(input("对方的ip:"))

    udpSocket = socket(AF_INET, SOCK_DGRAM)
    udpSocket.bind(("", 4567))

    tr = Thread(target=recvData)
    ts = Thread(target=sendData)

    tr.start()     #启动接收数据线程
    ts.start()     #启动发送数据线程

    tr.join()      #等待两个线程结束
    ts.join()

if __name__ == "__main__":
    main()

八、wireshark抓包工具的使用

wireshark工具可以抓取当前电脑中所有网络数据,具体如图所示:

九、tftp下载器的使用(tftpd64或tftpd32)

tftp是tcp/ip协议族中用来将客户端和服务器之间进行简单文件传输的协议。

特点如下:

基于UDP实现,可能会丢包,实现过程为收到-回复,下载过程如下:

TFTP数据包格式如下:

读写请求格式:操作码为1或2,分别表示读或写;文件名为文件名称;0为固定写法;模式有几种,最常用的为octet;最后跟一个0。

数据包格式:操作码固定为3;文件名为文件名称;块编号为文件分割的块编号;数据为详细数据。

确认格式:操作码固定为4;块编号为确认收到的文件分块编号。

错误包格式:操作码固定为5;差错码为固定好的错误编号;后面接具体差错信息;最后跟一个0;

注意:确认包发往的是服务器发送本地进程时分配的随机端口!

怎样确定数据已经发送完毕了?

规定, 当客户端接收到的数据⼩于516(2字节操作码+2个字节的序号+512字节数据) 时, 就意味着服务器发送完毕了。
怎样保证包中每个码的字节数?

python中组包代码如下:

!:表示网络中的数据,网络中的数据用大端表示。

H:占用2个字节,对应后面的1。

8s:占用8个字节,对应后面的"test.jpg"。

b:占用1个字节,对应后面的0。

5s:占用5个字节,对应后面的"octet"。

b:占用1个字节,对应后面的0。

包格式如图所示:

使用python从tftp服务器中下载文件

1)首先启动tftpd64应用程序,设置好下载的目录和ip地址。

2)python代码如下:

# -*- coding:utf-8 -*-

import struct
from socket import *
import time
import os

def main():


	#0. 获取要下载的文件名字:
	downloadFileName = raw_input("请输入要下载的文件名:")	

	#1.创建socket
	udpSocket = socket(AF_INET, SOCK_DGRAM)

	requestFileData = struct.pack("!H%dsb5sb"%len(downloadFileName), 1, downloadFileName, 0, "octet", 0)

	#2. 发送下载文件的请求
	udpSocket.sendto(requestFileData, ("192.168.119.215", 69))

	flag = True #表示能够下载数据,即不擅长,如果是false那么就删除
	num = 0
	f = open(downloadFileName, "w")

	while True:
		#3. 接收服务发送回来的应答数据
		responseData = udpSocket.recvfrom(1024)

		# print(responseData)
		recvData, serverInfo = responseData

		opNum = struct.unpack("!H", recvData[:2])

		packetNum = struct.unpack("!H", recvData[2:4])

		print(packetNum[0])

		# print("opNum=%d"%opNum)
		# print(opNum)

		# if 如果服务器发送过来的是文件的内容的话:
		if opNum[0] == 3: #因为opNum此时是一个元组(3,),所以需要使用下标来提取某个数据
			

			#计算出这次应该接收到的文件的序号值,应该是上一次接收到的值的基础上+1
			num = num + 1

			# 如果一个下载的文件特别大,即接收到的数据包编号超过了2个字节的大小
			# 那么会从0继续开始,所以这里需要判断,如果超过了65535 那么就改为0
			if num==65536:
				num = 0

			# 判断这次接收到的数据的包编号是否是 上一次的包编号的下一个
			# 如果是才会写入到文件中,否则不能写入(因为会重复)
			if num == packetNum[0]:
				# 把收到的数据写入到文件中
				f.write(recvData[4:])
				num = packetNum[0]

			#整理ACK的数据包
			ackData = struct.pack("!HH", 4, packetNum[0])
			udpSocket.sendto(ackData, serverInfo)

		elif opNum[0] == 5:
			print("sorry,没有这个文件....")
			flag = False

		# time.sleep(0.1)

		if len(recvData)<516:
			break

	if flag == True:
		f.close()
	else:
		os.unlink(downloadFileName)#如果没有要下载的文件,那么就需要把刚刚创建的文件进行删除

if __name__ == '__main__':
	main()

十、UDP广播

UDP广播不是对每个用户轮流发送数据,而是发送到交换机,交换机负责同时发送给每个用户。

广播可用于动态获取ip地址。

单播----点对点;多播----一对多;广播----一对所有。

注意:广播只用于UDP中,TCP不能广播!

python简单实现:

十一、TCP服务器、客户端简介及实现

11.1 TCP简介

tcp:传输控制协议

特点:1、稳定;2、相对udp而言要慢一些;3、web服务器都是使用的tcp;

udp:用户数据包协议

特点:1、不稳定;2、相对tcp而言要快一些;

11.2 TCP和UDP通信模型

udp通信模型:相当于写信;

tcp通信模型:相当于打电话;

 socket创建出来的套接字,默认为主动套接字,即发送数据给别人。listen()将主动套接字变为被动套接字。

TCP服务器端:

1、买个手机  socket(xxx);

2、插入手机卡  bind(xxx);

3、设置手机为响铃模式  listen();

4、等待别人的电话,准备好接听  accept();

TCP客户端:

1、买个手机  socket(xxx);

2、拨打电话  connect(xxx);

11.3 python实现tcp服务器和客户端

tcp服务器端实现(简单原理实现,非实际的多进程)如下:

注意:

accept用来接收客户端请求,并重新创建一个socket为新的客户服务,然后等待下一个客户端的请求。

clientSocket用来专门为新的客户端服务。

代码解释:

第一个while循环用来监听是否有新客户接入,并为它分配服务资源。 

第二个while循环为新的客户端服务。注意:当客户端下线时,newSocket.recv(1024)这句可以解阻塞,且返回值为0,从而可以跳出循环。

 该程序为单任务,实际服务器为多进程实现,只需将第二个while定义为一个函数,在第一个while中启动一个进程执行该函数即可。

#coding=utf-8
from socket import *
# 创建socket
tcpSerSocket = socket(AF_INET, SOCK_STREAM)
# 绑定本地信息
address = ('', 7788)
tcpSerSocket.bind(address)

# 使⽤socket创建的套接字默认的属性是主动的, 使⽤listen将其变为被动的, 这样就可以接收。
# 5表示服务器同一时刻最多允许5个客户端发数据
tcpSerSocket.listen(5)

while True:
# 如果有新的客户端来链接服务器, 那么就产⽣⼀个新的套接字专⻔为这个客户端服务器
# newSocket⽤来为这个客户端服务
# tcpSerSocket就可以省下来专⻔等待其他新客户端的链接
newSocket, clientAddr = tcpSerSocket.accept()

    # 该循环为新的客户端服务。注意:当客户端下线时,newSocket.recv(1024)这句可以解阻塞,且返回
    # 值为0,从而可以跳出循环
    while True:
        # 接收对⽅发送过来的数据, 最⼤接收1024个字节
        recvData = newSocket.recv(1024)

        # 如果接收的数据的⻓度为0, 则意味着客户端关闭了链接
        if len(recvData)>0:
            print 'recv:',recvData
        else:
            break

        # 发送⼀些数据到客户端
        sendData = raw_input("send:")
        newSocket.send(sendData)

    # 关闭为这个客户端服务的套接字, 只要关闭了, 就意味着为不能再为这个客户端服务了
    newSocket.close()

# 关闭监听套接字, 只要这个套接字关闭了, 就意味着整个程序不能再接收任何新的客户端的连接
tcpSerSocket.close()

tcp客户器端实现如下:

from socket import *

#创建TCP套接字
clientSocket = socket(AF_INET, SOCK_STREAM)
#链接服务器
clientSocket.connect(("192.168.119.153", 8989))

#注意:
# 1. tcp客户端已经链接好了服务器,所以在以后的数据发送中,不需要填写对方的iph和port----->打电话
# 2. udp在发送数据的时候,因为没有之前的链接,所依需要 在每次的发送中 都要填写接收方的ip和port----->写信 

#发送数据
clientSocket.send("haha".encode("gb2312"))
#接收数据
recvData = clientSocket.recv(1024)
#打印接收到的数据
print("recvData:%s"%recvData)
#关闭客户端socket
clientSocket.close()

 

1、网络编程基础:从拓扑到协议的全面解析 本文全面解析了网络编程的基础知识,从常见的网络拓扑结构到带宽与延迟的关系,再到OSI参考模型的分层功能,涵盖了网络通信的核心概念。文章还介绍了使用Go语言进行网络编程的学习目标、适用场景以及相关技术,如套接字编程、应用层协议交互和数据序列化等。无论你是网络编程的新手还是有经验的开发者,都能从中获得有价值的参考信息。 阅读详情

相关推荐

别再对着数据手册发愁了!用HFSS 2023 R2搞定ESP32-C3板载天线的阻抗匹配

本文详细介绍了如何利用HFSS 2023 R2进行ESP32-C3板载天线的阻抗匹配优化,解决实际PCB设计中常见的性能偏差问题。通过智能模型导入、科学参数扫描和量化优化流程,显著提升天线性能,适用于WIFI和蓝牙应用场景。

weixin_42523543的博客 448

网络编程(TCP/IP协议+UDP/IP协议)

我们每天打开浏览器浏览网页时,浏览器的进程怎么与web服务器通信的?当你用QQ聊天时,QQ进程怎么与服务器或你好友所在的QQ进程通信?这些都得靠socket?那什么是socket?本文就介绍了其相关的基础内容。例如:网络编程,其中包括网络通信介绍、TCP/IP协议(重点掌握)、UDP/IP协议以及这两个协议的具体对比(掌握)等等。。...

m0_59016750的博客 1501

大模型驱动时序量化因子自动优化:从WorldQuant回测到实战策略

本文探讨了如何利用大模型驱动时序量化因子的自动优化,构建从创意生成到实战验证的完整流程。通过结合WorldQuant回测平台,搭建自动化流水线,详细拆解了因子生成、回测验证与迭代优化的核心模块。文章分享了从初版实现到进阶优化的实践经验,并指出提示词工程与领域知识注入是关键,旨在实现人机智能协作,提升量化策略研发效率。

wdx012345的博客 803

Python 网络编程:实现各种协议

TCP/IP(Transmission Control Protocol/Internet Protocol)是一组用于在网络上进行通信的协议。TCP 提供可靠的数据传输,而 IP 负责将数据包从一个网络节点路由到另一个网络节点。UDP(User Datagram Protocol)是一种无连接的协议,它提供了快速的数据传输,但不保证数据的可靠性。HTTP(Hypertext Transfer Protocol)是用于在 Web 上传输超文本的协议。

m0_57836225的博客 1186

银河麒麟V10开机卡Logo?别慌,手把手教你进单用户模式修复(附详细命令)

本文详细解析银河麒麟V10操作系统启动时卡Logo的故障原因,并提供进入单用户模式的完整解决方案。通过GRUB引导菜单修改启动参数,执行文件系统检查、图形服务修复等关键命令,帮助用户快速恢复系统正常运行,适用于运维人员和普通用户应对紧急启动问题。

weixin_30522183的博客 392

CTP高频Tick数据:五档期货Level2深度解析20241224

高频Tick五档期货Level2数据,作为一种先进的金融市场分析工具,以其一秒四次的高频更新,为投资者揭示了市场的微观结构。本文将深入探讨这一数据如何帮助投资者洞察市场动态,优化交易策略,实现投资收益的最大化。

level2Tick的博客 1218

网络编程(TCP/UDP)

TCP/UDP

qq_63250428的博客 1415

以太网GMAC-RK3568

第 2 章和第 3 章中针对 RMII/RGMII 接口芯片和 USB 以太网两种类型芯片在 SDK 上的配置做详细的描述,第 4 章介绍以太网在 Android 上的相关调用接口。第 5 章提供常见问题的排查建议由于在 RK 系列的 SoC 中内置了以太网 MAC 控制器,所以只需要搭配一颗以太网 PHY 芯片,即可实现以太网卡功能按照规范,即使是不同厂家的 PHY,仍然有一部分寄存器的定义是通用的,只要配置了这些通用的寄存器,基本上 PHY 就可以正常工作代码位置在。

qq_24093081的博客 1943

Linux网络编程一(协议、TCP、UDP、socket编程、TCP服务器端及客户端)

(User Datagram Protocol),IP负责把数据包送到正确的计算机中,UDP负责把数据包送到正确的程序,UDP不提供数据修复和重发的机制,且无法知道数据包是否送达,数据的确实不重要但是快!16位:目的端口号,如:微信端口号是8080,则送入到微信程序中。),它位于网络协议栈的传输层,负责在通信的两个应用程序之间提供可靠的、面向连接的数据传输服务。②注册端口:1024~49151,随意使用,用于松散的绑定一些程序/服务。4、目的IP:32位对应4字节,Ip地址共4字节,每个字段上限255。

DZJ_Nirvana 1725

SAP ABAP CO核心扩展-ZCKMLQS 多物料工厂的评估数量结构报表(CKMLQS)

CKMLQS 只能查看单一物料工厂的评估数量结构,SAP 没有提供多物料工厂的评估数量结构报表。这篇文章将实现 CO核心扩展-ZCKMLQS 多物料工厂的评估数量结构报表。

SAP李斌,本人承诺所有原创文章均不使用任何AI生成技术,请大家放心阅读。 1089

MTK Meta ISP 工具使用技巧与参数读取路径全解析

在联发科(MediaTek, MTK)平台上进行相机图像调试时,Meta ISP 工具是连接 PC 与设备进行参数调整、寄存器读取和图像输出的重要工具。本文以实战角度出发,系统梳理 Meta ISP 的使用流程、关键模块功能、典型调试技巧与参数读取路径,结合最新版平台(如MTK Genio/Dimensity 系列)架构,帮助工程师掌握联发科图像调优的核心流程。

努力分享一些人工智能、计算机视觉、影像等相关的知识干货! 1148

二、网络编程之协议及协议格式详解

在网络编程中,我经常听人提起过协议,标准协议、协议族、TCP协议、传输层协议......诸如此类的协议概念。 这些种类繁多的协议听着让人感觉头晕,所以学习和总结协议的相关知识!

weixin_45004203的博客 3212

ESP32-C3入门教程 WiFi篇①——WiFi Scan 扫描附近AP无线热点 | 堵塞等待扫描结果,回调事件通知扫描结果

文章目录一、快速运行二、运行效果三、程序流畅四、关键函数4.1 扫描所有有效的AP4.2 获取上次扫描中找到的AP列表4.3 获取上次扫描中找到的AP数 一、快速运行 示例项目中,选择WiFi—>scan menuconfig配置ESP32C3-Specific—>Rec 0 芯片选择ESP32-C3(Built-in USB JTAG) 快速运行ESP-IDF Build, Flash and Monitor(左下角) 二、运行效果 三、程序流畅 esp_netif_init,初始

5417

网络编程【1】网络基础协议

OSI七层网络协议 经典协议与数据包 三次握手与四次挥手 TCP拥塞控制 为啥会出现粘包、拆包,如何处理? 基于golang实现TCP、UDP、Http服务端与客户端

jstang的博客 3888

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

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

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

网络编程基础——网络协议(1)

1.网络编程 软件开发架构 c/s 架构 c:客户端 s:服务端 b/s 架构 b:浏览器 s:服务器 手机端:好像c/s架构比较火,其实不然,比如微信小程序、支付宝第三方服务,为了统一接口! pc端:b/s比较火 本质:b/s其实也是c/s 服务端:24小时不间断提供服务,谁来我就...

iskwiw的博客 297

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

linux:网络编程 《网络基础1》《协议分层》《UDP通信》

1.网络基础: 网络的发展以及一些网络编程的知识点: 局域网:网络覆盖范围1000米以内的网络 城域网:网络覆盖一个城市的范围 广域网:网络覆盖范围通常在20千米以上 互联网,公网,因特网----国际化的超大型广域网 组网方式:以太网 ip地址是无符号四个字节的整数,那么IP地址总共也就43亿个。全世界够分吗? IP地址版本的区分: ipv4:无符号四个字节的整数,不够用,解决方案:DHCP技术—动态地址分配技术;NAT技术—网络地址转换技术 ipv6:无符号六个字节的数据,但是目前ipv6,推广难度高,到

weixin_45726063的博客 182

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

第1章 网络编程基础(1)——网络协议

网络游戏类型:开发的角度 对等的客户端与服务器端 基于大厅的网络游戏 纯C/S结构的网络游戏 网络通信协议 协议(Protocol):两个实体间控制数据交换的规则的集合。 语法(数据格式、编码、信号电平等) 语义(包括用于协调和进行差错处理的控制信息) 定时(包括速度匹配和排序等) OSI模型: 高层协议偏重于处理用户服务和各种应用请求 底层协议偏重...

deo91209的博客 230

java网络编程协议与基础1—基本网络概念

网络分层 1、java网络编程中采用的是internet的TCP/IP四层模型 主要包括 *应用层 *传输层 *网际层 *物理路径 各个层运行的协议 网际层:IP协议,也是java唯一理解的网络层协议 传输层:     - TCP:保证了数据包按照发送时的顺序进行传送以及对丢失和破坏的数据进行重传,但是开销 比较大     - UDP:

code_AC的博客 748

网络编程学习笔记(1)--TCP/IP协议基础

TCP/IP协议簇按照从上到下可以分为四个层:应用层、传输层、网际层、网络接口层(数据链路层)

张张的博客 1212

Android基础入门教程——7.1.1 Android网络编程要学的东西与Http协议学习

答:hypertext transfer protocol(超文本传输协议),TCP/IP协议的一个应用层协议,用于定义WEB浏览器与WEB服务器之间交换数据的过程。客户端连上web服务器后,若想获得web服务器中的某个web资源,需遵守一定的通讯格式,HTTP协议用于定义客户端与web服务器通迅的格式。...

m0_67391518的博客 188

JavaSE基础(day21)(1)网络编程的常识 (2)基于tcp协议的编程模型(3)tcp协议和udp协议的比较 (4)基于udp协议的编程模型

1.画图题 画出所学IO流类之间的关系。 2.编程题 使用实现继承的方式启动一个线程,在该线程中每隔一秒打印一次当前系统时间,主线程等待5秒之后停止子线程。 今天内容: (1)网络编程的常识 (2)基于tcp协议的编程模型 (3)tcp协议和udp协议的比较 (4)基于udp协议的编程模型 1.网络编程的常识(记住) 目前主流的网络通讯软件有:QQ、微信、飞信、阿里旺旺、… 1.1 七层网络协议模...

程序员哦的博客 373

Linux网络编程基础1(网络应用程序设计模式,分层模型,协议格式)

Linux网络编程基础(网络应用程序设计模式,socket编程,inet_pton,inet_ntop,服务端创建连接的过程,客户端创建连接的过程,socket函数封装)1. 网络应用程序设计模式2. 分层模型3. 协议3.1 协议的概念3.2 协议格式3.2.1 以太网帧格式 -- 借助mac地址完成数据报传递3.2.2 IP段格式3.2.3 UDP数据包格式3.2.4 TCP数据报格式4. 数据的发送和接收5. TCP/UDP简要 1. 网络应用程序设计模式 1. C/S - client/server

kuanyew的博客 1317

java基础(4)——网络编程(1)IP、端口、 通信协议

文章目录IP端口通信协议 IP ip地址:InetAddress 唯一定位一台网络计算机 127.0.0.1 本机localhost ip地址分类 ipv4和ipv6 ipv4 :长度为 32 位(4 个字节) ipv6 :长度为 128 位(16 个字节) 公网-私网 A类地址范围:1.0.0.0~127.255.255.255 B类地址范围:128.0.0.1~191.255.255.255。 C类地址范围:192.0.0.1~223.255.255.255。 D类地址范围:22

赶路de人的博客 205
上一篇: linux脚本编程基础
下一篇: 网络编程——2、通信基础
ACanswer
博客等级 码龄12年 280粉丝 42原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值