用C++实现最基本的Socket通讯(一)

【Windows】 C++实现 Socket 通讯 阅读详情

前言闲聊

冬去春来,想着今年定个小目标,逐步实现TCP和UDP的通讯连接,自定义通讯协议,几种I/O模型(阻塞,非阻塞,I/O多路复用,IOCP),当中会涉及到许多知识,就我目前的知识水平大概了解有多线程,线程锁,生产者消费者模式,观察者模式,Json序列化,心跳监听等。在此分类的文章我尽量使用面向对象的思想来写,因为本人也才接触服务器不久,希望在文中出现了错误,或是有一些更好的方法或建议,希望不吝赐教,共同进步。如果所写文章能够对你有所帮助,点个赞便是对我最大的鼓励。

简单的服务器

我用win32控制台创建一个SocketServerTest类

//SocketServerTest.h
    
#ifndef _H_SERVERTEST_
#define _H_SERVERTEST_

#include <WinSock2.h>

#pragma comment(lib, "ws2_32.lib")  //加载 ws2_32.dll

class SocketServerTest
{
public:
	SocketServerTest();
	~SocketServerTest();

	bool createSocket();//创建socket
	bool bandSocket(const char* ip, const unsigned short prot);//绑定本地地址和端口号
	bool listenSocket();//初始化监听并设置最大连接等待数量
	SOCKET acceptSocket();//接受请求连接的请求,并返回句柄
	void recvSocket(SOCKET& recvsocket);//接受客服端数据
	void sendSocket(SOCKET& sendsocket);//发送客户端数据
	void closeMySocket();//关闭连接

private:
	SOCKET m_nServerSocket;//绑定本地地址和端口号的套接口
};

#endif

下面我打算先实现一个简单的功能,就是一个客服端与我连接成功,我返回一个连接服务器成功消息,然后接下来等待客服端发来的消息,接受到之后,我返回一个消息接受成功,并关闭连接。

//ServerTest.cpp
#include "ServerTest.h"
#include <iostream>

using namespace std;

SocketServerTest::SocketServerTest():m_nServerSocket(-1)
{
	WSADATA wsaData;
	if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
		cout << "Socket版本错误" << endl;
}

SocketServerTest::~SocketServerTest()
{
	closeMySocket();
}

void SocketServerTest::closeMySocket()
{
	if (m_nServerSocket != -1)
		closesocket(m_nServerSocket);	//关闭socket连接

	m_nServerSocket = -1;
	WSACleanup();	//终止ws2_32.lib的使用
}

bool SocketServerTest::createSocket()
{
	if (m_nServerSocket == -1)
	{
		m_nServerSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);	//设定TCP协议接口;失败返回INVALID_SOCKET
		if (m_nServerSocket != INVALID_SOCKET) 
		{
			cout << "服务器启动成功" << endl;
			return true;
		}
	}
	return false;
}

bool SocketServerTest::bandSocket(const char* ip, const unsigned short prot)
{
	int nRet = -1;
	if (m_nServerSocket != -1)
	{
		sockaddr_in Serveraddr;
		memset(&Serveraddr, 0, sizeof(sockaddr_in*));
		Serveraddr.sin_family = AF_INET;
		Serveraddr.sin_addr.s_addr = inet_addr(ip);
		Serveraddr.sin_port = htons(prot);
		nRet = bind(m_nServerSocket, (sockaddr *)&Serveraddr, sizeof(Serveraddr));	//绑定服务器地址和端口号;成功,返回0,否则为SOCKET_ERROR
	}

	if (nRet == 0)
	{
		cout << "绑定IP和端口成功" << endl;
		return true;
	}

	cout << "绑定IP和端口失败" << endl;
	return false;
}

bool SocketServerTest::listenSocket()
{
	int nRet = -1;
	if (m_nServerSocket != -1)
	{
		nRet = listen(m_nServerSocket, 5);//设定接受连接的套接字,以及设定连接队列长度;成功返回0,失败返回-1
	}
	if (nRet == SOCKET_ERROR)
	{
		cout << "监听绑定失败" << endl;
		return false;
	}
		
	cout << "监听绑定成功" << endl;
	return true;
}

SOCKET SocketServerTest::acceptSocket()
{
	SOCKET sClient = 0;
	sockaddr_in nClientSocket;
	int nSizeClient = sizeof(nClientSocket);
	while (m_nServerSocket != -1)
	{
		sClient = accept(m_nServerSocket, (sockaddr*)&nClientSocket, &nSizeClient);//接受客户端连接,阻塞状态;失败返回-1
		if (sClient == SOCKET_ERROR)
		{
			cout << "accept连接失败" << endl;
			return 0;
		}

		cout << "连接一个客户端成功" << endl;

		char mess[] = "sercer:与服务器连接成功!";
		send(sClient, mess, sizeof(mess), 0);//发送消息给客户端
		recvSocket(sClient);//接受客户端的消息
	}
	return 0;
}

void SocketServerTest::recvSocket(SOCKET& recvsocket)
{
	while (recvsocket != 0)
	{
		// 从客户端接收数据
		char buff[256];
		int nRecv = recv(recvsocket, buff, 256, 0);//从客户端接受消息
		if (nRecv > 0)
		{
			cout << buff << endl;
			char mess[] = "server:收到了你的消息,欢迎下次使用!";
			send(recvsocket, mess, sizeof(mess), 0);
			closesocket(recvsocket);
			recvsocket = 0;
		}
		else
		{
			cout << "客户端退出" << endl;
			return;
		}
	}
}

简单的客户端

我用win32控制台创建一个ClientSocketTest类,跟服务器结构大同小异,主要在于listen()和connect()上

//ClientSocketTest.h
#ifndef _CHIENTSOCKET_H_
#define _CHIENTSOCKET_H_

#include <WinSock2.h>
#pragma comment(lib, "ws2_32.lib")  //加载 ws2_32.dll

class ClientSocketTest
{
public:
	ClientSocketTest();
	~ClientSocketTest();

	bool createSocket();
	void closeSocket();

	bool Myconnect(const char* ip, const unsigned short prot);
	void Mysend();
	void Myrecv();

	void outputMessage(const char* outstr);

private:
	SOCKET m_nLocalSocket;
	char m_message[100];
};

#endif

接下来我的想法是,首先连接服务器,收到服务器的确认消息后,发送消息给服务器,等待服务器返回,然后断开连接。

//ClientSocketTest.cpp
#include "ClientSocketTest.h"
#include <iostream>
#include <thread>

ClientSocketTest::ClientSocketTest()
{
	m_nLocalSocket = -1;
	WSADATA wsaData;
	if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
		std::cout << "Socket版本加载失败" << std::endl;
}

ClientSocketTest::~ClientSocketTest()
{
	closeSocket();
}

void ClientSocketTest::closeSocket()
{
	if (m_nLocalSocket != -1)
		closesocket(m_nLocalSocket);	//关闭socket连接

	m_nLocalSocket = -1;
	WSACleanup();	//终止ws2_32.lib的使用
}

//创建一个socket
bool ClientSocketTest::createSocket()
{
	if (m_nLocalSocket == -1)
	{
		m_nLocalSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
		if (m_nLocalSocket != INVALID_SOCKET)
		{
			outputMessage("客服端socket创建成功");
			return true;
		}
	}
	
	outputMessage("客服端socket创建成功");

	return false;
}

bool ClientSocketTest::Myconnect(const char* ip, const unsigned short prot)
{
	int nRet = SOCKET_ERROR;
	if (m_nLocalSocket != -1)
	{
		sockaddr_in m_nServeraddr;
		memset(&m_nServeraddr, 0, sizeof(m_nServeraddr));
		m_nServeraddr.sin_family = AF_INET;
		m_nServeraddr.sin_port = htons(prot);
		m_nServeraddr.sin_addr.s_addr = inet_addr(ip);
		nRet = connect(m_nLocalSocket, (sockaddr*)&m_nServeraddr, sizeof(m_nServeraddr));//成功返回0。否则返回SOCKET_ERROR

		if (nRet == SOCKET_ERROR)
		{
			outputMessage("服务器连接失败!");
			return false;
		}

		outputMessage("服务器连接成功!");
		Myrecv();

		return true;
	}

	return false;
}

void ClientSocketTest::Myrecv()
{
	if (m_nLocalSocket != -1)
	{
		int resultRecv = -1;
		while (true)
		{
			resultRecv = recv(m_nLocalSocket, m_message, sizeof(m_message), 0);
			if (resultRecv > 0)
			{
				//输出消息
				outputMessage(m_message);
				memset(m_message, '\0', sizeof(m_message));
				Mysend();
			}
			else
			{
				//这几种错误码,认为连接是正常的,继续接收
				if ((resultRecv < 0) && (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR))
				{
					continue;//继续接收数据
				}
				outputMessage("与服务器连接中断!");
				break;//跳出接收循环
			}
		}
	}
	else
	{
		outputMessage("当前与服务器未连接!");
	}
}

void ClientSocketTest::Mysend()
{
	if (m_nLocalSocket != -1)
	{
		char buffer5[100] = "client:客户端连接测试成功!";
		send(m_nLocalSocket, buffer5, sizeof(buffer5), 0);
	}
	else
	{
		outputMessage("当前与服务器未连接");
	}
}

void ClientSocketTest::outputMessage(const char * outstr)
{
	std::cout << outstr << std::endl;
}

启动程序

在此之前,我们还有个头文件myDefine.h没有写,下面我把代码贴上

//myDefine.h
#ifndef _MYDEFINE_H_
#define _MYDEFINE_H_

#define MYSERVERIP	"127.0.0.1"
#define MYPROT	16000

#endif

然后依次启动服务器和客户端代码

   //服务器启动
    #include "stdafx.h"
    #include <iostream>
    #include "ServerTest.h"
    #include "myDefine.h"
    
    int main()
    {
    	SocketServerTest* sserverTest = new SocketServerTest();
    	sserverTest->createSocket();
    	sserverTest->bandSocket(MYSERVERIP, MYPORT);
    	sserverTest->listenSocket();
    	sserverTest->acceptSocket();
    	delete sserverTest;
    
    	system("pause");
    	return 0;
    }

//客户端启动
#include "stdafx.h"
#include "ClientSocketTest.h"
#include "myDefine.h"

int main()
{
	ClientSocketTest* sockettest = new ClientSocketTest();
	sockettest->createSocket();
	sockettest->Myconnect(MYSERVERIP, MYPROT);
	delete sockettest;

	system("pause");
	return 0;
}

运行后结果

总结

这是最简单的阻塞socket通讯,服务器既不能满足并发,客户端也没有使用多线程,会在主线程中阻塞,而且通讯也只是一对一的,因为你会发现服务器必须断开第一个客户端连接之后才会接着处理第二个客户端连接。在下一章我会实现一对多的通讯,当然还是阻塞模式,结构跟上述代码不会相差太大,觉得能学到东西的朋友可以自己尝试一下。以后的代码如果实在过多,我会挑一些重点的部分粘贴出来,然后源码会提交在gitHub上,代码太累赘大家看着也比较吃力。

跨平台(Windows+Linux)的Socket通讯程序(一)—底层封装 【摘要】编写Socket通讯程序是一个老话题。本文重点介绍Windows平台和Linux平台Socket通讯的不同,采用C++,编制了一个简单的跨平台的Socket通讯库。 一、Socket通讯的基础知识 Socket通讯是两个计算机之间最基本的通讯方法,有TCP和UDP两种协议。关于这两种协议的区别,不少文章已有详述,这里,稍微总结一下: 1.TCP是面向连接的,是“流”式的,意即通讯两端 阅读详情

相关推荐

毫米波雷达IWR1843开箱演示

毫米波雷达IWR1843开箱演示

m0_56120826的博客 7778

c# socket接收字符串_网络编程——socket编程

socket编程什么是socket?简称套接字,是进程间通信的一种方式,它与其他进程间通信的一个主要不同是:它能实现不同主机间的进程间通信,我们网络上各种各样的服务大多数是基于socket来完成通信的。socket是基于C/S架构的,也就是说socket网络编程,通常需要写两个文件,一个服务端,一个客户端Python中的socket通信逻辑如下图所示在python中,用socket.socket(...

weixin_39629780的博客 425

无源低通滤波器

无源RC滤波器“滤除”不需要的信号,因为它们分离并允许仅通过其频率的正弦输入信号,最简单的是无源低通滤波器网络。在低频应用(高达100kHz)中,无源滤波器通常使用简单的RC(电阻-电容)网络构建,而高频滤波器(高于100kHz)通常由RLC(电阻-电感-电容)元件制成。无源滤波器由电阻器、电容器和电感器等无源元件组成,没有放大元件(晶体管、运算放大器等),因此没有信号增益,因此它们的输出电平始终小于输入。滤波器是根据它们允许通过它们的信号的频率范围来命名的,同时阻挡或“衰减”其余部分。

weixin_44448586的博客 1万+

什么时候采用socket通信,什么时候采用http通信

什么时候采用socket通信,什么时候采用http通信。 问题1:什么是socket通信,什么是http通信。 socket通信是对TCP/IP协议的封装(封装了tcp/ip协议让我们操作更加方便),http协议是应用层协议。 问题2:两者的区别 Http连接:http连接就是所谓的短连接,及客户端向服务器发送一次请求,服务器端相应后连接即会断掉。 socket连接:socket连接是长连接,理论上客户端和服务端一旦建立连接,则不会主动断掉;但是由于各种环境因素可能会是连接断开,比如说:服务器端或客户

等一轮明月的博客 1890

国家医保移动支付国密算法SM2签名验签、SM4加解密DLL

DLL,非.net开发,所以无需安装配置,直接程序引用开发即可,支持各类开发语言。已知省份有广西、贵州、安徽、河北、黑龙江、湖南、吉林、江苏、四川、新疆等各地方。国家医保移动支付国密算法SM2签名验签、SM4加解密DLL。//SM4加密与解密。支持医保移动支付(国家统一版),//SM2签名与验签。

4265

Win11内核隔离无法打开的解决方案详解

内核隔离问题的解决需遵循"先硬件后软件"的排查原则,90%以上的案例可通过驱动清理或外设断开解决。对于必须禁用该功能的用户,建议定期使用Windows Defender进行全盘扫描,并保持系统更新至最新版本。技术决策需在安全性和兼容性之间取得平衡,本文提供的多维解决方案可帮助用户构建更稳定的Windows 11使用环境。

mmoo_python的博客 4830

C/C++语言实现WiFi(socket)数据收发(客户端和服务端)

C/C++语言实现WiFi(socket)数据收发(客户端和服务端) C/C++实现TCP通信、接收WIFI数据

XiaoCaiDaYong的博客 4199

Cox构建预测模型(5):如何用R语言绘制校准曲线(附全套代码)

这篇文献通过绘制两个模型的DCA曲线来评估模型的临床决策实际需求,一个是列线图模型,包括纳入列线图的全部变量,一个是TNM模型,只纳入TNM分期3个变量。A图是训练集1年、3年、5年患者的总生存期的DCA曲线;B图是训练集1年、3年、5年患者的总生存期的DCA曲线,红色线条代表列线图模型(包括构建模型的10个变量),黄色线条代表TNM模型(仅纳入TNM分期3个变量),两个模型对比,在绘制校准图之前,必须要完成数据的导入、拆分数据集的工作、预测因子的筛选,校准图的绘制是分别在训练集与验证集独立进行的。

qq_37610365的博客 1360

socket 远程主机强迫关闭了一个现有的连接_C++ | socket笔记

socketsocket是使用标准Unix文件描述符(file descriptor)和其它程序通讯的方式。internet套接字的两种类型其实有多种类型,常用两种是stream sockets流格式和datagram sockets数据包格式。其中前者是可靠的双向通讯的数据流,使用TCP协议;后者是无连接套接字,使用UDP协议。涉及的结构体 套接字用到的各种数据类型socket描述符,类型是in...

weixin_39599342的博客 1274

基于FPGA的ov5640摄像头简易图像采集装置详解

本文介绍一种基于FPGA的,通过流模式DDR实现OV5640摄像头数据采集并显示的方法。

qq_42230252的博客 1万+

wintab开发例程

 タブレットとスタイラスペンを使うと、パソコンに手書きの線を入力できます。筆圧を入力することができるので毛筆のような表現も可能です。ペンの傾きを入力できる機種もあり、アイデア次第で面白いことに使えそうです。  私は昔(94年頃)、WACOMのタブレットを用いたプログラム開発をしたことがあります。当初A3版ほどの大きさのUDというタブレットを使っていて、その後 ArtPad という小さいサイズの

grass168的专栏 3242

Socket通信总结(附C++实现)

文章目录 [隐藏] 一、Socket是什么 二、一些基本概念 三、java socket建立连接的过程   四、Socket 通信示例 五、建立通信链路 六、服务端代码: 七、客户端代码 测试图例:        因为项目需要,服务端需要一个SOCKET来接收客户端的请求,好吧,没办法度娘哇,结果很多都是linux的例子,功夫不负有心人啊

冷月宫主的专栏 5728

2️⃣ Coze创建智能体教学(2025年全新版本)

扣子平台提供强大支持,可将智能体轻松集成至各类社交平台,使智能体得以服务更为庞大的用户群体。当下支持集成的平台如下:​1️⃣豆包:作为聚焦 AI 内容创作的平台,非常适合发布充满创意、娱乐性强的智能体。​2️⃣飞书:适合发布用于办公协作的智能体,助力团队提升工作效率。​3️⃣微信:借助公众号或小程序的形式,能够服务海量微信用户。​4️⃣抖音:适合发布与短视频相关的智能体,为用户提供创意与娱乐服务。​

李同学Lino的博客 4581

【C++网络编程】Socket基础:网络通讯程序入门级教程

本篇博文介绍了C++网络编程的基础知识,从Socket基础到Epoll的使用,为初学者提供了入门级的教程。读者将学习如何创建套接字、建立连接、发送和接收数据,并深入了解Epoll在高性能网络编程中的应用。

朝花夕拾 7640

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

蓝牙模块HM-10手册

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

C++实现的socket基础通讯

网络通讯是指两台计算机中的程序进行传输数据的过程。客户程序(客户端):指主动发起通讯的程序服务程序(服务端/服务器):被动的等待,然后为向它发起通讯的客户端提供服务通讯前,客户端必须提前知道服务端的IP地址和端口,而服务端不需要知道客户端的IP。

quinii的博客 1844

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

用C++实现简单的一对多Socket通讯(二)

回顾 上一篇文章实现了一个最简单的socket连接,但只能进行一对一通讯,所以本篇文章将会将功能扩展下,实现一对多的通讯方式。上篇实现代码中,感谢@rf_versace指出服务器接受数据的容器太小,容易溢出,这点之前没有想到过,目前解决的方法就是设置大一点,一般来说消息都会有序列化和反序列化,关于序列化和反序列化之后再写一篇文章来说下。 一个多线程服务器 和上一篇文章一样,我们初始化sock...

立于浮华之世,奏出天使之章 2952

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

CPP进程间的通讯

本文介绍了C++中进程间通信(IPC)的两种主要方式:管道和消息队列。 管道通信: 分为匿名管道(pipe)和命名管道(mkfifo) 匿名管道用于父子进程通信,通过pipe()创建 命名管道可通过文件名访问,适用于无亲缘关系的进程 注意管道是单向通信,需要妥善关闭不使用的端口 消息队列: 重点介绍了ZeroMQ的实现方式 详细说明了PUSH-PULL模式的使用方法 推送端(PUSH)绑定端口发送消息,拉取端(PULL)连接端口接收消息 简要提及了其他通信模式(REQ-REP、PUB-SUB等) 文中提供

2301_80440354的博客 1383

C++ socket 简单通讯

一、socket通讯开发步骤 1、创建socket 1.1、指定服务端相关信息系 指定socket版本号 如: winsock_ver = MAKEWORD(2, 2); addr_len = sizeof(SOCKADDR_IN); //指定ip地址族 addr_svr.sin_family = AF_INET; //转换网络编码,指定侦听本地端口 addr_svr.sin_port = ::...

print_out的博客 1579

Linux环境下使用c++通过Socket套接字实现CAN通讯

本文介绍了如何在Linux环境下,使用C语言通过Socket套接字实现CAN协议通讯。对Socket套接字中需要使用的函数、传参及函数返回值等细节问题做出了详细的解释。

weixin_45496000的博客 3834

Socket通讯

Socket(套接字)是网络编程的抽象接口,用于实现不同设备(或进程)之间的网络通信。它本质上是一个“通信端点”,通过操作系统提供的 API 屏蔽了底层网络协议的复杂细节,让开发者可以通过简单的函数调用实现数据传输。

eatbaozi的博客 2396

C++:实现socket通信(TCP/IP)实例

首先声明,博主之前从来没有写过通信方面的东西,这次之所以写这个是因为项目需要,因此本文主要介绍一个使用C++语言及Socket来实现TCP/IP通信的实例,希望可以帮助入门者。 一、什么是TCP/IP? TCP提供基于IP环境下的数据可靠性传输,事先需要进行三次握手来确保数据传输的可靠性。详细的博主不再赘述,感兴趣的朋友可以去search一下。 二、什么是soc...

Cche的博客 19万+

Linux C++ UDP Socket(超详细)

​ 使用UDP协议进行信息的传输之前不需要建议连接。换句话说就是客户端向服务器发送信息,客户端只需要给出服务器的ip地址和端口号,然后将信息封装到一个待发送的报文中并且发送出去。至于服务器端是否存在,或者能否收到该报文,客户端根本不用管。 ​ 通常用于实时性较高,数据量较大,丢一两帧影响不大的情况。如视频聊天 电话聊天 传感器广播消息 汽车发送位置信息等 。 环境:Linux 语言:C++ 通讯方式:UDP 1. udp 通讯的流程 下图是一个UDP通讯的时序图:实现客户端发消息到服务器端。 #me

休息一下接着来的博客 1万+

erlang 实现与 c++ 通讯

网络通讯常用的有2种:文本通讯和二进制通讯。行通讯是一种文本通讯,格式如“cmd args\n”,比较简单,erlang接收数据也比较简单,可以设置参数{packet, line},缺点是表示方式单一,很难表示结构数据。包体通讯是二进制通讯,目前主要有结构体,json,asn等等。文章分别在两种方式上实现erlang与c++通讯。

没有开花的树 4168

C++实现Windows下服务端与客户端Socket通信(一)

C++实现Windows下服务端与客户端Socket通信,实现Socket传输结构体、类对象数据,以及应用Protobuf数据序列化。Socket+Protobuf+MFC.

abcdefz的博客 8023

基于 HPSocket , 实现 socket 通讯

HP-Socket 是一套通用的高性能 TCP/UDP/HTTP 通信框架,包含服务端组件、客户端组件和 Agent 组件,广泛适用于各种不同应用场景的 TCP/UDP/HTTP 通信系统,提供 C/C++、C#、Delphi、E(易语言)、Java、Python 等编程语言接口。HP-Socket 对通信层实现完全封装,应用程序不必关注通信层的任何细节;HP-Socket 提供基于事件通知模型的 API 接口,能非常简单高效地整合到新旧应用程序中。

J。 7622

Linux环境下使用c++通过Socket套接字实现UDP协议通讯

本文详细介绍了如何在Linux环境下,使用c++通过Socket套接字实现UDP协议通讯。对Socket套接字中需要使用的函数、传参及函数返回值等细节问题做出了详细的解释。本文源码可以直接运行使用。

weixin_45496000的博客 2121
下一篇: 用C++实现简单的一对多Socket通讯(二)
two L
博客等级 码龄11年 12粉丝 6原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值