点对点聊天和多对点聊天程序的详尽阐述

项目场景:

简述项目相关背景:

项目场景:通过在VS或VC++的环境下,实现ch5点对点聊天和ch5多对点聊天功能。使用C++语言,与MFC有关。(MFC是微软提供的类库,引申为一种语言)


问题描述

项目中遇到的问题:

( 一 ) 代码拷贝过来后不知道如何打开:
( 二 ) 引用的源文件不存在:
( 三 ) MFC不清楚是什么,更别谈下载:
( 四 ) Gi 与Bi,zi不兼容:

原因分析:

( 一 ) 代码打不开是很多新手锁遇到的问题,如果只是一个单独的 .cpp 或 .h 文件还比较好处理,带面对一个小型的工程项目,面对逐渐复杂的文件组织架构,我需要明白各种文件类型的作用,常见的有
.exe 程序文件 。
应用程序 。
.sln(Visual Studio Solution) 通过对环境提供项目,项目项和解决项目项在
磁盘位置上的引用,可将他们组织到解决方案中。
即生成的是Debug模式还是Release模式,是通用CPU还是专用的。
.suo(solution user operation) 解决方案用户选项记录所有将与方案关联的
选项
( 二 )引用的源文件不存在,可能有多种原因。我所遇到的是程序兼容性问题。除去代码本身的问题,需要调整的是“项目右键–>属性–>C/C++
–>常规
–>调试信息格式–>程序数据库”。
还有一种情况根据“扬我大山东"博主依次点击“项目–>配置属性–>C/C++
–>常规
–>附加包含目录中加入.h 文件所在文件夹路径
这种方式没试过,不太清楚,由于我的项目里有三个以上的.h文件,所以不清楚要添加哪个文件,亦或是全部添加而且中间用英文分号隔开。我尝试过将某个.h的完整路径添加过去,但毫无效果。由于多个错误混杂在一起,我陷入了一个误区,就是逐个调错,搞不清楚大环境,结果不言而喻。也因此交了学费。
解决源文件不存在与不兼容问题

( 三 ) 第三点,建造项目工程是需要营造一个环境的,在C++语言中常做的是调用函数,调用内部库,调用外部依赖库(python),所以当MFC库不存在时,要考虑是否存在这个库,这个库与环境建立链接。我是这么理解的,环境相对于库相当于一个瓶子,库相当于星星,把星星提前放进瓶子,后人才可以从瓶子中取出星星。MFC在第一次安装VS时,见过,但不清楚怎么打开界面。具体打开方式: 工具–>获取工具和功能–>单个组件
在这里插入图片描述

( 四 )不兼容
导致不兼容与源文件不一致的原因不同,但是神奇的是解决方法相同,我想可能是因为我的包目录下有.sdf 数据库文件。
VS2015与VS2022有不兼容问题。

部分点对点聊天代码如下:
客户端

// MySocket.cpp : implementation file
//

#include "stdafx.h"//声明文件
#include "talkc.h"
#include "MySocket.h"
#include "TalkcDlg.h"

#if !defined(AFX_MYSOCKET_H__9741667D_315B_4915_BCDE_9F2125BA065C__INCLUDED_)
#define AFX_MYSOCKET_H__9741667D_315B_4915_BCDE_9F2125BA065C__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// MySocket.h : header file
//


class CTalkcDlg;
/
// CMySocket command target

class CMySocket : public CAsyncSocket
//继承CAsyncSocket的派生类CMySocket
{
// Attributes
public:

// Operations
public:
	CMySocket();//构造函数
	virtual ~CMySocket();//析构虚函数

// Overrides
public:
	void SetParent(CTalkcDlg* pDlg);
	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CMySocket)
	public:
	virtual void OnConnect(int nErrorCode);
	virtual void OnReceive(int nErrorCode);
	virtual void OnClose(int nErrorCode);
	//}}AFX_VIRTUAL

	// Generated message map functions
	//{{AFX_MSG(CMySocket)
		// NOTE - the ClassWizard will add and remove member functions here.
	//}}AFX_MSG

// Implementation

private:
	CTalkcDlg* m_pDlg;
};

/
// stdafx.cpp : source file that includes just the standard includes
//	talkc.pch will be the pre-compiled header
//	stdafx.obj will contain the pre-compiled type information

#include "stdafx.h"
// stdafx.h : include file for standard system include files,
//  or project specific include files that are used frequently, but
//      are changed infrequently
//

#if !defined(AFX_STDAFX_H__10C4D7CE_2F14_4619_B8F2_38D0A55A6568__INCLUDED_)
#define AFX_STDAFX_H__10C4D7CE_2F14_4619_B8F2_38D0A55A6568__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#define VC_EXTRALEAN		// Exclude rarely-used stuff from Windows headers

#include <afxwin.h>         // MFC core and standard components
#include <afxext.h>         // MFC extensions
#include <afxdisp.h>        // MFC Automation classes
#include <afxdtctl.h>		// MFC support for Internet Explorer 4 Common Controls
#ifndef _AFX_NO_AFXCMN_SUPPORT
#include <afxcmn.h>			// MFC support for Windows Common Controls
#endif // _AFX_NO_AFXCMN_SUPPORT

#include <afxsock.h>		// MFC socket extensions
/ talkc.cpp : Defines the class behaviors for the application.
//

#include "stdafx.h"
#include "talkc.h"
#include "talkcDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
// talkc.h : main header file for the TALKC application
//

#if !defined(AFX_TALKC_H__53578CD9_66CB_4FEC_ADBE_E8BEBAA6565C__INCLUDED_)
#define AFX_TALKC_H__53578CD9_66CB_4FEC_ADBE_E8BEBAA6565C__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#ifndef __AFXWIN_H__
	#error include 'stdafx.h' before including this file for PCH
#endif

#include "resource.h"		// main symbols

/
// talkcDlg.cpp : implementation file
//

#include "stdafx.h"
#include "talkc.h"
#include "talkcDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/
// talkcDlg.h : header file
//

#if !defined(AFX_TALKCDLG_H__AC4F7955_1012_4B99_946D_E63FFC0AD185__INCLUDED_)
#define AFX_TALKCDLG_H__AC4F7955_1012_4B99_946D_E63FFC0AD185__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "MySocket.h" 
/
// CTalkcDlg dialog

在这里插入图片描述
服务端

部分多对点聊天代码如下:

#if !defined(AFX_MYSOCKET_H__9CFF521D_4D98_4B9D_BC7D_ED9424D34D3B__INCLUDED_)
#define AFX_MYSOCKET_H__9CFF521D_4D98_4B9D_BC7D_ED9424D34D3B__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// MySocket.h : header file
//

class CTalksDlg;

//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by talks.rc
// Resource.h
//
#define IDM_ABOUTBOX                    0x0010
#define IDD_ABOUTBOX                    100
#define IDS_ABOUTBOX                    101
#define IDD_TALKS_DIALOG                102
#define IDP_SOCKETS_INIT_FAILED         103
#define IDR_MAINFRAME                   128
#define IDC_EDIT_SERVNAME               1000
#define IDC_EDIT_SERVPORT               1001
#define IDC_EDIT_MSG                    1002
#define IDC_BUTTON_LISTEN               1003
#define IDC_BUTTON_CLOSE                1004
#define IDC_LIST_SENT                   1005
#define IDC_LIST_RECEIVED               1006
#define IDC_STATIC_SERVNAME             1007
#define IDC_STATIC_SERVPORT             1008
#define IDC_STATIC_MSG                  1009
#define IDC_STATIC_SENT                 1010
#define IDC_STATIC_RECEIVED             1011

// stdafx.h : include file for standard system include files,
//  or project specific include files that are used frequently, but
//      are changed infrequently
//

#if !defined(AFX_STDAFX_H__E985166D_524A_4949_AC97_DCF04A9E0EBC__INCLUDED_)
#define AFX_STDAFX_H__E985166D_524A_4949_AC97_DCF04A9E0EBC__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#define VC_EXTRALEAN		// Exclude rarely-used stuff from Windows headers

#include <afxwin.h>         // MFC core and standard components
#include <afxext.h>         // MFC extensions
#include <afxdisp.h>        // MFC Automation classes
#include <afxdtctl.h>		// MFC support for Internet Explorer 4 Common Controls
#ifndef _AFX_NO_AFXCMN_SUPPORT
#include <afxcmn.h>			// MFC support for Windows Common Controls
#endif // _AFX_NO_AFXCMN_SUPPORT

// talks.h : main header file for the TALKS application
//

#if !defined(AFX_TALKS_H__A2EF205B_CB6F_438F_BB7B_23168390D760__INCLUDED_)
#define AFX_TALKS_H__A2EF205B_CB6F_438F_BB7B_23168390D760__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#ifndef __AFXWIN_H__
	#error include 'stdafx.h' before including this file for PCH
#endif

#include "resource.h"		// main symbols

/
// CTalksApp:
// See talks.cpp for the implementation of this class
//
// talksDlg.h : header file
//

#if !defined(AFX_TALKSDLG_H__A13FF4B7_2D85_4211_81BC_2B11109251C0__INCLUDED_)
#define AFX_TALKSDLG_H__A13FF4B7_2D85_4211_81BC_2B11109251C0__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "MySocket.h" 
/
// CTalksDlg dialog

class CTalksDlg : public CDialog
{
// Construction
public:	
	CMySocket m_sListenSocket;
	CMySocket m_sConnectSocket;
	void OnConnect();
	void OnAccept();
	void OnReceive();
	void OnClose();
	CTalksDlg(CWnd* pParent = NULL);	// standard constructor

// Dialog Data
	//{{AFX_DATA(CTalksDlg)
	enum { IDD = IDD_TALKS_DIALOG };
	CButton		m_btnListen;
	CListBox	m_listSent;
	CListBox	m_listReceived;
	CString		m_strServName;
	CString		m_strMsg;
	int			m_nServPort;
	//}}AFX_DATA

	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CTalksDlg)
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV support
	//}}AFX_VIRTUAL

// Implementation
protected:
	HICON m_hIcon;

	// Generated message map functions
	//{{AFX_MSG(CTalksDlg)
	virtual BOOL OnInitDialog();
	afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
	afx_msg void OnPaint();
	afx_msg HCURSOR OnQueryDragIcon();
	afx_msg void OnButtonListen();
	afx_msg void OnButtonClose();
	afx_msg void OnSendMsg();
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

// MySocket.cpp : implementation file
//

#include "stdafx.h"
#include "talks.h"
#include "MySocket.h"
#include "TalksDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/
// CMySocket

CMySocket::CMySocket()
{
	//put the member pointer to NULL
	m_pDlg=NULL;
}
// stdafx.cpp : source file that includes just the standard includes
//	talks.pch will be the pre-compiled header
//	stdafx.obj will contain the pre-compiled type information

#include "stdafx.h"

// talks.cpp : Defines the class behaviors for the application.
//

#include "stdafx.h"
#include "talks.h"
#include "talksDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/
// CTalksApp
// talksDlg.cpp : implementation file
//

#include "stdafx.h"
#include "talks.h"
#include "talksDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

服务器端

多点聊天

// CSocket.h: interface for the CCSocket class.
//
//

#if !defined(AFX_CSOCKET_H__INCLUDED_)
#define AFX_CSOCKET_H__INCLUDED_

class CTcDlg;

class CCSocket : public CSocket  
{
	DECLARE_DYNAMIC(CCSocket);


//Construction
public:
	CCSocket(CTcDlg* pDlg);  //构造函数
	virtual ~CCSocket();     //析构函数

// Attributes
public:
	CTcDlg* m_pDlg;          //成员变量

//Implementation
protected:
	virtual void OnReceive(int nErrorCode);  //事件处理函数
};

#endif // !defined(AFX_CSOCKET_H__INCLUDED_)

// Msg.h: interface for the CMsg class.
//
//

#if !defined(AFX_MSG_H__INCLUDED_)
#define AFX_MSG_H__INCLUDED_

//消息类的定义
class CMsg : public CObject  
{
	DECLARE_DYNCREATE(CMsg);

public:
	CMsg();            //构造函数
	virtual ~CMsg();   //析构函数
	virtual void Serialize(CArchive& ar);  //序列化函数

//Attributes
public:
	CString m_strBuf;       //字符串成员
	BOOL m_bClose;          //是否关闭状态
};
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by tc.rc
//
#define IDM_ABOUTBOX                    0x0010
#define IDD_ABOUTBOX                    100
#define IDS_ABOUTBOX                    101
#define IDD_TC_DIALOG                   102
#define IDP_SOCKETS_INIT_FAILED         103
#define IDR_MAINFRAME                   128
#define IDC_EDIT_CNAME                  1000
#define IDC_EDIT_SNAME                  1001
#define IDC_EDIT_PORT                   1002
#define IDC_BUTTON_CONN                 1003
#define IDC_EDIT_MSG                    1004
#define IDC_STATIC_CNAME                1005
#define IDC_STATIC_SNAME                1006
#define IDC_STATIC_PORT                 1007
#define IDC_STATIC_MSG                  1008
#define IDC_BUTTON_CLOSE                1009
#define IDC_LIST_MSG                    1010
// stdafx.h : include file for standard system include files,
//  or project specific include files that are used frequently, but
//      are changed infrequently
//

#if !defined(AFX_STDAFX_H__E2C4D328_FDB8_11D9_BC43_000795DF7F99__INCLUDED_)
#define AFX_STDAFX_H__E2C4D328_FDB8_11D9_BC43_000795DF7F99__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#define VC_EXTRALEAN		// Exclude rarely-used stuff from Windows headers
// tc.h : main header file for the TC application
//

#if !defined(AFX_TC_H__E2C4D324_FDB8_11D9_BC43_000795DF7F99__INCLUDED_)
#define AFX_TC_H__E2C4D324_FDB8_11D9_BC43_000795DF7F99__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#ifndef __AFXWIN_H__
	#error include 'stdafx.h' before including this file for PCH
#endif

#include "resource.h"		// main symbols

/
// CTcApp:
// See tc.cpp for the implementation of this class
//

class CTcApp : public CWinApp
{
public:
	CTcApp();

// Overrides
	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CTcApp)
	public:
	virtual BOOL InitInstance();
	//}}AFX_VIRTUAL

// Implementation

	//{{AFX_MSG(CTcApp)
		// NOTE - the ClassWizard will add and remove member functions here.
		//    DO NOT EDIT what you see in these blocks of generated code !
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

// tcDlg.h : header file
//

#if !defined(AFX_TCDLG_H__E2C4D326_FDB8_11D9_BC43_000795DF7F99__INCLUDED_)
#define AFX_TCDLG_H__E2C4D326_FDB8_11D9_BC43_000795DF7F99__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

/
// CTcDlg dialog

#include  "CSocket.h"

class CTcDlg : public CDialog
{
// Construction
public:

	CTcDlg(CWnd* pParent = NULL);	// standard constructor
// CSocket.cpp: implementation of the CCSocket class.
//
//

#include "stdafx.h"
#include "tc.h"
#include "CSocket.h"
#include "tcDlg.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//
// Construction/Destruction
//
IMPLEMENT_DYNAMIC(CCSocket,CSocket)

//构造函数
CCSocket::CCSocket(CTcDlg* pDlg)
{
	m_pDlg = pDlg;       //成员变量赋值
}

CCSocket::~CCSocket()
{
	m_pDlg = NULL;
}

//事件处理函数,当套接字收到FD_READ消息时,执行此函数
void CCSocket::OnReceive(int nErrorCode) 
{
	CSocket::OnReceive(nErrorCode);
	//调用CTcDlg类的相应函数处理
	if (nErrorCode == 0) m_pDlg->OnReceive();
}
// Msg.cpp: implementation of the CMsg class.
//
//

#include "stdafx.h"
#include "tc.h"
#include "Msg.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//
// Construction/Destruction
//
//构造函数
CMsg::CMsg()
{
	m_strBuf=_T("");         //初始化
	m_bClose=FALSE;
}

//析构函数
CMsg::~CMsg()
{
}

//序列化函数
void CMsg::Serialize(CArchive& ar)
{
	if (ar.IsStoring())
	{
		ar<<(WORD)m_bClose;
		ar<<m_strBuf;
	} else {
		WORD wd;
		ar>>wd;
		m_bClose=(BOOL)wd;
		ar>>m_strBuf;
	}
	//m_msgList.Serialize(ar);
}

IMPLEMENT_DYNAMIC(CMsg,CObject)
// stdafx.cpp : source file that includes just the standard includes
//	tc.pch will be the pre-compiled header
//	stdafx.obj will contain the pre-compiled type information

#include "stdafx.h"

// tc.cpp : Defines the class behaviors for the application.
//

#include "stdafx.h"
#include "tc.h"
#include "tcDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/
// CTcApp

BEGIN_MESSAGE_MAP(CTcApp, CWinApp)
	//{{AFX_MSG_MAP(CTcApp)
		// NOTE - the ClassWizard will add and remove mapping macros here.
		//    DO NOT EDIT what you see in these blocks of generated code!
	//}}AFX_MSG
	ON_COMMAND(ID_HELP, CWinApp::OnHelp)
END_MESSAGE_MAP()
// tcDlg.cpp : implementation file
//

#include "stdafx.h"
#include "tc.h"
#include "tcDlg.h"
#include "CSocket.h"
#include "Msg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/
// CAboutDlg dialog used for App About

多点聊天客户机端
在这里插入图片描述

// CSocket.h: interface for the CCSocket class.
//
//

#if !defined(AFX_CSOCKET_H__INCLUDED_)
#define AFX_CSOCKET_H__INCLUDED_

class  CTsDlg;
class  CMsg;

//用于建立连接和传送接收信息的客户套接字类定义
class CCSocket : public CSocket  
{
	DECLARE_DYNAMIC(CCSocket);

//Construction
public:
	CCSocket(CTsDlg* pDlg);   //构造函数
	virtual ~CCSocket();      //析构函数

//Attributes
public:
	CTsDlg* m_pDlg;         //主对话框类指针变量
	CSocketFile* m_pFile;   //CSocketFile对象的指针变量
	CArchive* m_pArchiveIn; //用于输入的CArchive对象的指针变量
	CArchive* m_pArchiveOut;//用于输出的CArchive对象的指针变量

//Operations
public:
	void Initialize();               //初始化
	void SendMessage(CMsg* pMsg);    //发送消息
	void ReceiveMessage(CMsg* pMsg); //接收消息

//Overridable callbacks
//可重载的回调函数,当套接字收到数据时,自动调用此函数
protected:
	virtual void OnReceive(int nErrorCode);
};

#endif // !defined(AFX_CSOCKET_H__INCLUDED_)

// LSocket.h: interface for the CLSocket class.
//
//

#if !defined(AFX_LSOCKET_H__INCLUDED_)
#define AFX_LSOCKET_H__INCLUDED_

class  CTsDlg;

//专用于监听客户端连接请求的侦听套接字类定义
class CLSocket : public CSocket  
{
	DECLARE_DYNAMIC(CLSocket);

//Construction
public:
	CLSocket(CTsDlg* pDlg);
	virtual ~CLSocket();

// Attributes
public:
	CTsDlg* m_pDlg;   //成员变量

// Overridable Callbacks
//可重载的回调函数,当套接字收到连接请求时,自动调用此函数
protected:
	virtual void OnAccept(int nErrorCode);
};

#endif // !defined(AFX_LSOCKET_H__INCLUDED_)

// Msg.h: interface for the CMsg class.
//
//

#if !defined(AFX_MSG_H__INCLUDED_)
#define AFX_MSG_H__INCLUDED_

//消息类定义
class CMsg : public CObject  
{
	DECLARE_DYNCREATE(CMsg);

//Construction
public:
	CMsg();
	virtual ~CMsg();

//Attributes
public:
	CString m_strText;      //字符串成员
	BOOL m_bClose;          //是否关闭状态
	//Implementation
public:
	virtual void Serialize(CArchive& ar);   //序列化函数
};

#endif // !defined(AFX_MSG_H__INCLUDED_)

多点聊天服务器端
多点聊天服务器端

源文件找不到可能是路径有问题,也可能是没有加载MFC库。要知道MFC框架,MFC对象与windows对象的关系,消息映射的实现,MFC应用程序的执行过程。
其中调用的CAsyncSocket类,可以接受并处理的消息事件,连接的请求与接受,数据的发送和接受,关闭套接字和清除对象等。

例如:熟悉文件的打开方式,有框架知识,基于CAsyncSocket类的聊天程序,基于Csocket类的聊天程序
据数据库文件调整信息格式。


解决方案:

( 一 )点击.sln打开项目
( 二 )切换调试信息格式,项目–>属性–>C/C+±->t调试信息格式–>程序数据库
( 三 )安装MFC库,搭建框架 ,工具–>获取工具和功能–>单个组件包
( 四 ) 右键项目–>配置属性–>平台,选择需要的模式。

例如:单个组件包选择与MFC相关的包并下载。使用.sln 加载项目而不是.dll文件,运行exe文件,搭建框架。

谢谢大家
感谢“扬我大山东"的一篇文章等。

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

看似随意的良苦用心

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值