Skip to content

Instantly share code, notes, and snippets.

@M0nteCarl0
Created August 3, 2023 08:38
Show Gist options
  • Save M0nteCarl0/c060485525d9e168f261e63aa4c35977 to your computer and use it in GitHub Desktop.
Save M0nteCarl0/c060485525d9e168f261e63aa4c35977 to your computer and use it in GitHub Desktop.
Meizu project templates
#include <iostream>
#include <thread>
#include <vector>
#include <deque>
#include <mutex>
#include <condition_variable>
#include <boost/asio.hpp>
using boost::asio::ip::tcp;
// Constants
const int CONTROL_TASK_PORT = 20000;
const int SEND_TASK_PORT = 20001;
const int MAX_PAYLOAD_SIZE = 132;
// Command IDs
enum CommandID {
AUX_DEF_STAT = 0x10000,
AUX_LED_STAT,
AUX_SET_TIME,
// ... add more command IDs here
};
// Command structure
struct Command {
CommandID id;
char payload[MAX_PAYLOAD_SIZE];
};
// Thread-safe buffer for commands
class CommandBuffer {
public:
void addCommand(const Command& command) {
std::unique_lock<std::mutex> lock(mutex);
buffer.push_back(command);
lock.unlock();
condition.notify_one();
}
Command getCommand() {
std::unique_lock<std::mutex> lock(mutex);
condition.wait(lock, [this] { return !buffer.empty(); });
Command command = buffer.front();
buffer.pop_front();
return command;
}
private:
std::mutex mutex;
std::condition_variable condition;
std::deque<Command> buffer;
};
// Handle client connection
void handleClient(tcp::socket socket, CommandBuffer& commandBuffer) {
boost::system::error_code error;
Command command;
// Receive and process commands from the client
while (socket.read_some(boost::asio::buffer(&command, sizeof(Command)), error) > 0) {
// Process the command here
// ...
// Add the command to the buffer
commandBuffer.addCommand(command);
}
// Close the socket
socket.close();
}
// TCP server for control tasks
void controlTaskServer(CommandBuffer& commandBuffer) {
boost::asio::io_context ioContext;
tcp::acceptor acceptor(ioContext, tcp::endpoint(tcp::v4(), CONTROL_TASK_PORT));
while (true) {
tcp::socket socket(ioContext);
acceptor.accept(socket);
// Create a new thread to handle the client connection
std::thread clientThread(handleClient, std::move(socket), std::ref(commandBuffer));
clientThread.detach();
}
}
// TCP server for send tasks
void sendTaskServer(CommandBuffer& commandBuffer) {
boost::asio::io_context ioContext;
tcp::acceptor acceptor(ioContext, tcp::endpoint(tcp::v4(), SEND_TASK_PORT));
while (true) {
tcp::socket socket(ioContext);
acceptor.accept(socket);
// Create a new thread to handle the client connection
std::thread clientThread(handleClient, std::move(socket), std::ref(commandBuffer));
clientThread.detach();
}
}
int main() {
CommandBuffer commandBuffer;
// Start control task server
std::thread controlTaskThread(controlTaskServer, std::ref(commandBuffer));
controlTaskThread.detach();
// Start send task server
std::thread sendTaskThread(sendTaskServer, std::ref(commandBuffer));
sendTaskThread.detach();
// Run the main IO context
boost::asio::io_context ioContext;
ioContext.run();
return 0;
}
package main
import (
"fmt"
"net"
"sync"
)
// Constants
const (
CONTROL_TASK_PORT = ":20000"
SEND_TASK_PORT = ":20001"
MAX_PAYLOAD_SIZE = 132
)
// Command IDs
const (
AUX_DEF_STAT = 0x10000
AUX_LED_STAT
AUX_SET_TIME
// ... add more command IDs here
)
// Command structure
type Command struct {
ID int
Payload [MAX_PAYLOAD_SIZE]byte
}
// Thread-safe buffer for commands
type CommandBuffer struct {
mutex sync.Mutex
cond *sync.Cond
buffer []Command
}
// Add a command to the buffer
func (cb *CommandBuffer) addCommand(command Command) {
cb.mutex.Lock()
cb.buffer = append(cb.buffer, command)
cb.mutex.Unlock()
cb.cond.Signal()
}
// Get a command from the buffer
func (cb *CommandBuffer) getCommand() Command {
cb.mutex.Lock()
defer cb.mutex.Unlock()
for len(cb.buffer) == 0 {
cb.cond.Wait()
}
command := cb.buffer[0]
cb.buffer = cb.buffer[1:]
return command
}
// Handle client connection
func handleClient(conn net.Conn, commandBuffer *CommandBuffer) {
defer conn.Close()
// Receive and process commands from the client
for {
var command Command
err := readCommand(conn, &command)
if err != nil {
fmt.Println("Error reading command:", err)
break
}
// Process the command here
// ...
// Add the command to the buffer
commandBuffer.addCommand(command)
}
}
// Read a command from the connection
func readCommand(conn net.Conn, command *Command) error {
var buf [sizeofCommand]byte
n, err := conn.Read(buf[:])
if err != nil {
return err
}
if n != sizeofCommand {
return fmt.Errorf("Invalid command size")
}
// Unmarshal the command
// ...
return nil
}
// TCP server for control tasks
func controlTaskServer(commandBuffer *CommandBuffer) {
listener, err := net.Listen("tcp", CONTROL_TASK_PORT)
if err != nil {
fmt.Println("Error starting control task server:", err)
return
}
defer listener.Close()
for {
conn, err := listener.Accept()
if err != nil {
fmt.Println("Error accepting control task connection:", err)
continue
}
// Create a new goroutine to handle the client connection
go handleClient(conn, commandBuffer)
}
}
// TCP server for send tasks
func sendTaskServer(commandBuffer *CommandBuffer) {
listener, err := net.Listen("tcp", SEND_TASK_PORT)
if err != nil {
fmt.Println("Error starting send task server:", err)
return
}
defer listener.Close()
for {
conn, err := listener.Accept()
if err != nil {
fmt.Println("Error accepting send task connection:", err)
continue
}
// Create a new goroutine to handle the client connection
go handleClient(conn, commandBuffer)
}
}
func main() {
commandBuffer := &CommandBuffer{
cond: sync.NewCond(&sync.Mutex{}),
}
// Start control task server
go controlTaskServer(commandBuffer)
// Start send task server
go sendTaskServer(commandBuffer)
// Wait indefinitely
select {}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment