Newer
Older
casic_unitree_dog / src / tcp_service.cpp
//
// Created by casic on 25-2-25.
//

#include "tcp_service.hpp"
#include <iomanip>
#include <cerrno>
#include <vector>
#include <iostream>
#include <stdexcept>
#include <cstring>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>

static void handle_data_packet(std::vector<uint8_t> &data) {
    for (const uint8_t i: data) {
        std::cout << std::hex
                << std::uppercase
                << std::setw(2)
                << std::setfill('0')
                << static_cast<int>(static_cast<uint8_t>(i))
                << " ";
    }
    std::cout << std::endl;

    //转为std::vector<uint8_t>并发给机械臂串口
    std::vector command(data.begin(), data.end());
}

void TcpService::handle_client(const int client_socket) {
    std::vector<uint8_t> buffer;
    char byte;
    while (true) {
        const ssize_t bytes_received = recv(client_socket, &byte, 1, 0);
        if (bytes_received < 0) {
            std::cerr << "Failed to receive data: " << strerror(errno) << std::endl;
            close(client_socket);
            return;
        }

        if (bytes_received == 0) {
            std::cerr << "Connection closed by client" << std::endl;
            close(client_socket);
            return;
        }

        buffer.push_back(byte);

        if (static_cast<uint8_t>(byte) == 0xFA) {
            // 处理接收到的数据包
            if (!buffer.empty()) {
                handle_data_packet(buffer);
                buffer.clear(); // 清空缓冲区以接收下一个数据包
            }
        }
    }
}

void TcpService::start(const int port) {
    try {
        _socket_fd = socket(AF_INET, SOCK_STREAM, 0);
        if (_socket_fd == -1) {
            throw std::runtime_error("failed to create socket");
        }

        // 绑定套接字
        sockaddr_in server_addr = {};
        server_addr.sin_family = AF_INET;
        server_addr.sin_addr.s_addr = INADDR_ANY;
        server_addr.sin_port = htons(port);

        if (bind(_socket_fd, reinterpret_cast<sockaddr *>(&server_addr), sizeof(server_addr)) == -1) {
            throw std::runtime_error("failed to bind socket");
        }

        // 监听连接,最多允许5个连接
        if (listen(_socket_fd, 5) == -1) {
            throw std::runtime_error("failed to listen on socket");
        }

        std::cout << "TcpService started" << " and listening on port " << port << std::endl;

        // 接受连接
        while (true) {
            sockaddr_in client_addr{};
            socklen_t client_len = sizeof(client_addr);
            const int client_socket_fd = accept(_socket_fd, reinterpret_cast<sockaddr *>(&client_addr), &client_len);
            if (client_socket_fd == -1) {
                std::cerr << "failed to accept connection" << std::endl;
                continue;
            }

            std::cout << "Accepted connection from "
                    << inet_ntoa(client_addr.sin_addr)
                    << ":"
                    << ntohs(client_addr.sin_port)
                    << std::endl;

            // 处理连接
            _client_sockets.push_back(client_socket_fd);

            std::thread client_thread([this, client_socket_fd]() {
                this->handle_client(client_socket_fd);
            });
            client_thread.join();
        }
    } catch (const std::exception &e) {
        std::cerr << "exception in tcp_server::start: " << e.what() << std::endl;
    }
}

void TcpService::update_node(const int node) {
    std::stringstream ss;
    ss << node << ","
            << gas_value << ","
            << "116.296975" << ","
            << "39.990889"
            << std::endl;
    const std::string message = ss.str();
    std::cout << "TcpService update node: " << message << std::endl;
    for (const auto &client_socket: _client_sockets) {
        send(client_socket, message.c_str(), message.size(), 0);
    }
}

void TcpService::update_gas_value(const int value) {
    gas_value = value;
    std::cout << "TcpService update gas value: " << gas_value << " ppm·m" << std::endl;
}