在做stm32开发的时候,经常会去对接协议,特别是涉及到网络的时候,有时候调试起来又比较麻烦,在对接协议的时候,在协议层上,暂时是用不到操作硬件层面上的东西,只涉及到逻辑结构,所以通过编写一个c++网络服务端来进行对接,为了考虑移植性和代码编写方面,采用的C++编写,这个代码写完直接就可以复制到单片机工程里面。这里只关心协议逻辑,不关心tcp服务搭建的过程.具体代码如下:
#pragma comment (lib, "ws2_32.lib") //加载 ws2_32.dll
#include <Windows.h>
#include <cstdint>
#include <cstdio>
#include <iostream>
#include <thread>
#include <vector>
#include "Upgrage/upgrade_service.h"
/**
* \brief
*/
constexpr uint16_t BUF_SIZE = 2048;
void HandleClient(SOCKET client);
int main(int argc, char* argv[])
{
//初始化 DLL
WSADATA wsa_data;
WSAStartup(MAKEWORD(2, 2), &wsa_data);
//创建套接字
const SOCKET server_sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
//绑定套接字
sockaddr_in sock_addr = {};
sock_addr.sin_family = PF_INET; //使用IPv4地址
sock_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); //具体的IP地址
sock_addr.sin_port = htons(1234); //端口
bind(server_sock, reinterpret_cast<SOCKADDR*>(&sock_addr), sizeof(SOCKADDR));
//进入监听状态
listen(server_sock, 20);
//接收客户端请求
SOCKADDR client_addr;
int n_size = sizeof(SOCKADDR);
std::vector<std::thread> tcp_vec;
while (true)
{
SOCKET client = accept(server_sock, &client_addr, &n_size);
tcp_vec.emplace_back(HandleClient, client);
if(tcp_vec.back().joinable())
{
std::cout << "Tcp thread " << tcp_vec.back().get_id() << " is joinable!" << std::endl;
tcp_vec.back().detach();
}
// th1.join(); //等待t1退出
}
//向客户端发送数据
// const char* str = "Hello World!";
// send(client, str, strlen(str)+sizeof(char), NULL);
//关闭套接字
closesocket(server_sock);
//终止 DLL 的使用
WSACleanup();
return 0;
}
void HandleClient(SOCKET client)
{
uint8_t buf[BUF_SIZE];
upgrade_packet pkt;
while (true)
{
const int rec_len = recv(client, reinterpret_cast<char*>(buf), BUF_SIZE, 0);
if (rec_len <= 0) // 客户端断开连接之后,释放资源
{
closesocket(client);
printf("client closed\r\n");
break;
}
else
{
printf("rec data: %d\r\n", rec_len);
// todo 这里就是对接协议逻辑的处理代码
}
}
}