0
点赞
收藏
分享

微信扫一扫

【Socket网络编程】01(C++实例微信消息传到服务端)

心如止水_c736 2022-04-18 阅读 53
c++

项目需求

最近开发了一款微信助手小程序中控台,通过HOOK技术取到了微信的一些数据(聊天记录、昵称、好友列表)

现在需要微信在发送和获取聊天记录的第一时间,将聊天记录和一些信息发送到服务端,然后进行客户的记录和分析。

现在其他功能已经实现,界面是MFC写的,可以看一下。有点丑,不过是以功能为主,不需要太华丽。在这里插入图片描述

Socket实现步骤

客户端

1、初始化
2、创建套接字
3、绑定服务端 绑定IP和端口
4、服务端接收的是JSON,需要把数据存到结构体后再转换为JSON。
5、发送数据
6、关闭Socket
7、终止

	void Script1::CSocket(ChatMessageData* msg)
{
	//写入线程未处理
	
	//1	初始化
	WSADATA wsadata;
	WSAStartup(MAKEWORD(2, 2), &wsadata);
	//2	创建套接字
	SOCKET clientSocket = {};
	clientSocket = socket(PF_INET, SOCK_STREAM, 0);
	if (SOCKET_ERROR == clientSocket) {
		//cout << "套接字闯创建失败!" << endl;
	}
	else {
		//cout << "套接字创建成功!" << endl;
	}
	//3	绑定套接字	指定绑定的IP地址和端口号
	sockaddr_in socketAddr;
	socketAddr.sin_family = PF_INET;
	socketAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");//8.140.116.255
	socketAddr.sin_port = htons(1234);
	int cRes = connect(clientSocket, (SOCKADDR*)&socketAddr, sizeof(SOCKADDR));
	if (SOCKET_ERROR == cRes) {
		//cout << "客户端:\t\t与服务器连接失败....." << endl;
		return ;
	}
	else {
		//cout << "客户端:\t\t与服务器连接成功....." << endl;
		return ;
	}


	//		4	将结构体转为JSON
	rapidjson::StringBuffer buf;
	rapidjson::Writer<rapidjson::StringBuffer> writer(buf);
	//rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buf); // it can word wrap
	writer.StartObject();
	CString A = msg->MyId;
	writer.Key("code"); writer.Int(2);
	writer.Key("msg"); writer.String((char*)(wchar_t*)msg->MyId);
	writer.EndObject();
	const char* content = buf.GetString();//{"code":1,"msg":"1","time":"1649831773","data":null}


	//	5	发送数据
	//在发送结构体的受强制转换 提供地址形式发送即可	
	send(clientSocket, (char*)content, 4024, 0);
	//6	关闭socket
	closesocket(clientSocket);
	//7	终止
	WSACleanup();
	return ;
}

服务端

服务端不需要我写,就随便找了一套代码模拟一下就行。

1、初始化
2、创建套接字
3、指定绑定的IP地址和端口号
4、服务器监听
5、接收请求
6、接收数据、发送数据
7、关闭Socket
8、终止

int main()
{
	//	1	初始化
	WSADATA wsadata;
	WSAStartup(MAKEWORD(2, 2), &wsadata);	//make word,你把鼠标移到WSAStartup看看参数列表,是不是就是一个word啊

	//	2	创建服务器的套接字
	SOCKET serviceSocket;
	serviceSocket = socket(AF_INET, SOCK_STREAM, 0);	//socket(协议族,socket数据传输方式,某个协议)	我们默认为0,其实就是一个宏
	if (SOCKET_ERROR == serviceSocket) {


		cout << "套接字闯创建失败!" << endl;
		sockaddr_in socketAddr;

	}
	else {
		cout << "套接字创建成功!" << endl;

	}


	//	3	绑定套接字	指定绑定的IP地址和端口号
	sockaddr_in socketAddr;								//一个绑定地址:有IP地址,有端口号,有协议族
	socketAddr.sin_family = AF_INET;
	socketAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");		//代码开头第一行我们定义的宏在这就其作用啦
	socketAddr.sin_port = htons(1234);
	int bRes = bind(serviceSocket, (SOCKADDR*)&socketAddr, sizeof(SOCKADDR));	//绑定注意的一点就是记得强制类型转换
	if (SOCKET_ERROR == bRes) {
		cout << "绑定失败!" << endl;
	}
	else {
		cout << "绑定成功!" << endl;
	}

	//	4	服务器监听	
	int lLen = listen(serviceSocket, 5);	//监听的第二个参数就是:能存放多少个客户端请求,到并发编程的时候很有用哦
	if (SOCKET_ERROR == lLen) {
		cout << "监听失败!" << endl;
	}
	else {
		cout << "监听成功!" << endl;
	}
	//	5	接受请求
	sockaddr_in revClientAddr;
	SOCKET recvClientSocket = INVALID_SOCKET;	//初始化一个接受的客户端socket
	int _revSize = sizeof(sockaddr_in);
	recvClientSocket = accept(serviceSocket, (SOCKADDR*)&revClientAddr, &_revSize);
	if (INVALID_SOCKET == recvClientSocket) {
		cout << "服务端接受请求失败!" << endl;
	}
	else {
		cout << "服务端接受请求成功!" << endl;
	}
	//	6	发送/接受 数据
	char recvBuf[4024] = {};

	while (true)
	{
		//	6	发送/接受 数据
		int reLen = recv(recvClientSocket,recvBuf,4024, 0);
		if (SOCKET_ERROR != reLen) {
			cout << "服务端输出接受数据:  " << endl;
			//wprintf(student.MyID);
			memset(&recvBuf, 0, 4024);

		}
		//	7	关闭socket
	}

	closesocket(recvClientSocket);
	closesocket(serviceSocket);
	//	8	终止
	WSACleanup();

	cout << "服务器停止" << endl;
	cin.get();
	return 0;
}

需要注意的是传输和接收的参数包括参数长度要一致,也就是send 和 recv 参数要一致。
下一步会更深度的学习一下Socket和网络编程。

举报

相关推荐

0 条评论