Skip to content

Commit

Permalink
add ldou & rename shared-memory
Browse files Browse the repository at this point in the history
  • Loading branch information
jrtx0 committed Jan 14, 2025
1 parent 8cd7c69 commit 74117d3
Show file tree
Hide file tree
Showing 6 changed files with 330 additions and 0 deletions.
73 changes: 73 additions & 0 deletions ldou/client.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
#include <stdio.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <unistd.h>
#include "ldou.h"

int main() {
int sockfd;
struct sockaddr_in servaddr, cliaddr;

// 创建 UDP socket
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd < 0) {
perror("Socket creation failed");
return -1;
}

memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
servaddr.sin_port = htons(12345);

// 构造 LDOU 数据包
ldou_packet_t packet;
packet.flag = 0x1234;
packet.len = 5;
packet.addr = 1;
packet.cmd = 2;
packet.data[0] = 3;
packet.data[1] = 4;
packet.sum = ldou_calculate_checksum(&packet);

// 构造发送缓冲区
uint8_t buffer[128] = {0};
buffer[0] = (uint8_t)(packet.flag >> 8);
buffer[1] = (uint8_t)(packet.flag & 0xFF);
buffer[2] = packet.len;
buffer[3] = packet.addr;
buffer[4] = packet.cmd;
memcpy(&buffer[5], packet.data, packet.len - 3);
buffer[2 + packet.len] = packet.sum;

// 发送数据包
ssize_t sent = sendto(sockfd, buffer, 3 + packet.len, 0, (const struct sockaddr *)&servaddr, sizeof(servaddr));
if (sent < 0) {
perror("Failed to send data");
close(sockfd);
return -1;
}

printf("Packet sent successfully\n");

// 接收响应
socklen_t len = sizeof(cliaddr);
size_t n = recvfrom(sockfd, buffer, sizeof(buffer), 0, (struct sockaddr *)&cliaddr, &len);
if (n < 0) {
perror("Failed to receive data");
close(sockfd);
return -1;
}

printf("Received response: ");

for (ssize_t i = 0; i < n; i++)
{
printf("%02X ", buffer[i]);
}
printf("\n");

close(sockfd);
return 0;
}
140 changes: 140 additions & 0 deletions ldou/ldou.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
#include "ldou.h"
#include <stdio.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <unistd.h>

static int socket_fd = -1;
static struct sockaddr_in remote_addr;

ldou_handler_t command_handler = NULL;

/**
* @brief 计算校验和
*/
uint8_t ldou_calculate_checksum(const ldou_packet_t *packet)
{
uint8_t sum = 0;

sum += (uint8_t)(packet->flag >> 8);
sum += (uint8_t)(packet->flag & 0xFF);
sum += packet->len;
sum += packet->addr;
sum += packet->cmd;

for (uint8_t i = 0; i < packet->len - 3; i++)
{
sum += packet->data[i];
}

return sum;
}

/**
* @brief 初始化 LDOU 协议
*/
int ldou_init(const char *bind_ip, uint16_t port)
{
if ((socket_fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
{
perror("Socket creation failed");
return -1;
}

struct sockaddr_in local_addr = {0};
local_addr.sin_family = AF_INET;
local_addr.sin_addr.s_addr = inet_addr(bind_ip);
local_addr.sin_port = htons(port);

if (bind(socket_fd, (const struct sockaddr *)&local_addr, sizeof(local_addr)) < 0)
{
perror("Socket bind failed");
return -1;
}

return 0;
}

/**
* @brief 接收数据并解析为 LDOU 数据包
*/
int ldou_receive(ldou_packet_t *packet)
{
uint8_t buffer[128] = {0};
socklen_t addr_len = sizeof(remote_addr);

ssize_t received = recvfrom(socket_fd, buffer, sizeof(buffer), 0, (struct sockaddr *)&remote_addr, &addr_len);

if (received <= 0)
{
perror("Failed to receive data");
return -1;
}

packet->flag = (uint16_t)buffer[0] << 8 | buffer[1];
packet->len = buffer[2];
packet->addr = buffer[3];
packet->cmd = buffer[4];

size_t data_size = packet->len - 3;

if (data_size > LDOU_MAX_DATA_SIZE)
{
return -2; // 数据过长
}

memcpy(packet->data, &buffer[5], data_size);
packet->sum = buffer[2 + packet->len];

uint8_t calculated_sum = ldou_calculate_checksum(packet);

return (calculated_sum == packet->sum) ? 0 : -3; // 校验和错误
}

/**
* @brief 发送 LDOU 数据包
*/
int ldou_send(const ldou_packet_t *packet)
{
uint8_t buffer[128] = {0};

buffer[0] = (uint8_t)(packet->flag >> 8);
buffer[1] = (uint8_t)(packet->flag & 0xFF);
buffer[2] = packet->len;
buffer[3] = packet->addr;
buffer[4] = packet->cmd;

memcpy(&buffer[5], packet->data, packet->len - 3);

buffer[packet->len + 2] = packet->sum;

ssize_t sent = sendto(socket_fd, buffer, packet->len + 3, 0, (struct sockaddr *)&remote_addr, sizeof(remote_addr));

if (send <= 0)
{
perror("Failed to send data");
return -1;
}

return 0;
}

/**
* @brief 注册命令处理回调函数
*/
void ldou_register_handler(ldou_handler_t handler)
{
command_handler = handler;
}

/**
* @brief 清理资源
*/
void ldou_cleanup()
{
if (socket_fd >= 0)
{
close(socket_fd);
}
}
47 changes: 47 additions & 0 deletions ldou/ldou.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#ifndef LDOU_H
#define LDOU_H

#include <stdint.h>
#include <stddef.h>

#define LDOU_FLAG1 0x7E7E
#define LDOU_FLAG2 0xE7E7
#define LDOU_BROADCAST_ADDR 0xFF
#define LDOU_MAX_DATA_SIZE 64

/**
* @brief LDOU 数据包结构
*/
typedef struct {
uint16_t flag; /// < 报文标志位
uint8_t len; /// < 报文长度(含地址、命令、数据和校验和)
uint8_t addr; /// < 目标地址
uint8_t cmd; /// < 命令字
uint8_t data[LDOU_MAX_DATA_SIZE]; /// 数据部分
uint8_t sum; /// 校验和
} ldou_packet_t;

typedef void (*ldou_handler_t)(const ldou_packet_t *request, ldou_packet_t *response);

extern ldou_handler_t command_handler;

extern uint8_t ldou_calculate_checksum(const ldou_packet_t *packet);

// 初始化接口
extern int ldou_init(const char *bind_ip, uint16_t port);

// 接收数据接口
extern int ldou_receive(ldou_packet_t *packet);

// 发送数据接口
extern int ldou_send(const ldou_packet_t *packet);

// 注册命令处理回调接口
void ldou_register_handler(ldou_handler_t handler);

// 清理资源接口
void ldou_cleanup();



#endif // LDOU_H
70 changes: 70 additions & 0 deletions ldou/server.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
#include "ldou.h"

void example_command_handler(const ldou_packet_t *request, ldou_packet_t *response)
{
printf("Received command: 0x%02X\n", request->cmd);
printf("Data length: %d\n", request->len - 3);

for (int i = 0; i < request-> len - 3; i++)
{
printf("Data[%d]: 0x%02X\n", i, request->data[i]);
}

// 填充应答包
response->flag = LDOU_FLAG2;
response->len = request->addr;
response->cmd = request->cmd;
response->len = 4;
response->data[0] = 0x00;
response->sum = ldou_calculate_checksum(response);
}

int main()
{
const char *bind_ip = "0.0.0.0";
uint16_t port = 12345;

if (ldou_init(bind_ip, port) != 0)
{
printf("Failed to initialize LDOU protocol.\n");
return -1;
}

printf("LDOU protocol initialized. Waiting for commands on %s:%d...\n", bind_ip, port);

// 注册命令处理函数
ldou_register_handler(example_command_handler);

while (1)
{
ldou_packet_t request;
ldou_packet_t response;

int result = ldou_receive(&request);

if (result == 0)
{
printf("Packet received successfully.\n");

// 调用命令处理函数
command_handler(&request, &response);

if (ldou_send(&response))
{
printf("Response sent successfully.\n");
}
else
{
printf("Failed to send response.\n");
}
}
else
{
printf("Error receiving packet: %d\n", result);
}
}

ldou_cleanup();

return 0;
}
File renamed without changes.
File renamed without changes.

0 comments on commit 74117d3

Please sign in to comment.