Files
VDES_Backend/报文模拟解析/vdes_simulator.c
2026-07-13 15:37:05 +08:00

210 lines
6.0 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <math.h>
// Windows专用网络头文件
#include <winsock2.h>
#include <ws2tcpip.h>
#include <windows.h>
#pragma comment(lib, "ws2_32.lib") // 链接Winsock库
#define PORT 8082
#define BUFFER_SIZE 4096
#define MAX_SHIPS 10
// 船舶数据结构体
typedef struct {
char mmsi[20];
double latitude;
double longitude;
double speed;
int course;
int heading;
int nav_status;
char timestamp[30];
char ship_name[50];
int ship_type;
double draught;
char destination[50];
char eta[30];
} VDESData;
// 生成随机浮点数 (min, max)
double rand_range(double min, double max) {
return min + (double)rand() / RAND_MAX * (max - min);
}
// 获取当前时间戳
void get_current_timestamp(char *buffer) {
time_t now = time(NULL);
struct tm *t = localtime(&now);
strftime(buffer, 30, "%Y-%m-%d %H:%M:%S", t);
}
// 生成未来时间戳
void get_future_timestamp(char *buffer, int days) {
time_t now = time(NULL);
now += days * 24 * 3600; // 添加天数
struct tm *t = localtime(&now);
strftime(buffer, 30, "%Y-%m-%d %H:%M:%S", t);
}
// 创建一批船舶数据
void create_vdes_data_batch(VDESData *batch, int count) {
for (int i = 0; i < count; i++) {
// 生成随机MMSI (336295959 - 336295969)
snprintf(batch[i].mmsi, 20, "%d", 336295959 + rand() % 11);
batch[i].latitude = round(rand_range(30.5, 31.0) * 1000000) / 1000000.0;
batch[i].longitude = round(rand_range(122.0, 123.0) * 1000000) / 1000000.0;
batch[i].speed = round(rand_range(0, 30) * 10) / 10.0;
batch[i].course = rand() % 360;
batch[i].heading = rand() % 360;
batch[i].nav_status = rand() % 9;
get_current_timestamp(batch[i].timestamp);
char ship_num[10];
snprintf(ship_num, 10, "%d", 1000 + rand() % 9000);
strcpy(batch[i].ship_name, "船舶_");
strcat(batch[i].ship_name, ship_num);
batch[i].ship_type = 1 + rand() % 99;
batch[i].draught = round(rand_range(1.0, 15.0) * 10) / 10.0;
char port_num[10];
snprintf(port_num, 10, "%d", 1 + rand() % 100);
strcpy(batch[i].destination, "港口_");
strcat(batch[i].destination, port_num);
get_future_timestamp(batch[i].eta, 1 + rand() % 7);
}
}
// 将船舶数据转换为JSON字符串
void vdes_data_to_json(VDESData *data, char *json, int index, int is_last) {
char buffer[1024];
snprintf(buffer, 1024,
"{"
"\"mmsi\":\"%s\","
"\"latitude\":%.6f,"
"\"longitude\":%.6f,"
"\"speed\":%.1f,"
"\"course\":%d,"
"\"heading\":%d,"
"\"nav_status\":%d,"
"\"timestamp\":\"%s\","
"\"ship_name\":\"%s\","
"\"ship_type\":%d,"
"\"draught\":%.1f,"
"\"destination\":\"%s\","
"\"eta\":\"%s\""
"}%s",
data->mmsi, data->latitude, data->longitude, data->speed,
data->course, data->heading, data->nav_status, data->timestamp,
data->ship_name, data->ship_type, data->draught, data->destination,
data->eta,
is_last ? "" : ",");
strcat(json, buffer);
}
int main() {
// 初始化Winsock
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
perror("WSAStartup failed");
exit(EXIT_FAILURE);
}
srand(time(NULL)); // 初始化随机种子
SOCKET server_fd, new_socket; // Windows下使用SOCKET类型
struct sockaddr_in address;
char opt = '1'; // Windows下需要char类型
int addrlen = sizeof(address);
char buffer[BUFFER_SIZE] = {0};
// 创建socket文件描述符
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {
perror("socket failed");
WSACleanup();
exit(EXIT_FAILURE);
}
// 设置socket选项 (Windows下只使用SO_REUSEADDR)
if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == SOCKET_ERROR) {
perror("setsockopt");
closesocket(server_fd);
WSACleanup();
exit(EXIT_FAILURE);
}
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(PORT);
// 绑定socket到端口
if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
perror("bind failed");
closesocket(server_fd);
WSACleanup();
exit(EXIT_FAILURE);
}
// 开始监听
if (listen(server_fd, 3) < 0) {
perror("listen");
closesocket(server_fd);
WSACleanup();
exit(EXIT_FAILURE);
}
printf("VDES数据模拟器正在运行监听端口 %d...\n", PORT);
// 接受客户端连接
if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (int*)&addrlen)) == INVALID_SOCKET) {
perror("accept");
closesocket(server_fd);
WSACleanup();
exit(EXIT_FAILURE);
}
printf("客户端已连接\n");
while (1) {
// 随机等待时间 (1-5秒)
int sleep_time = 1 + rand() % 5;
Sleep(sleep_time * 1000); // Windows下使用Sleep(毫秒)
// 随机生成1-10条船舶数据
int ship_count = 1 + rand() % MAX_SHIPS;
VDESData ships[ship_count];
create_vdes_data_batch(ships, ship_count);
// 转换为JSON数组
char json[BUFFER_SIZE] = "[";
for (int i = 0; i < ship_count; i++) {
vdes_data_to_json(&ships[i], json, i, (i == ship_count - 1));
}
strcat(json, "]");
printf("生成 %d 条船舶数据:\n%s\n", ship_count, json);
// 发送数据
if (send(new_socket, json, strlen(json), 0) == SOCKET_ERROR) {
perror("send failed");
break;
}
printf("数据已发送\n");
}
// 清理资源
closesocket(new_socket);
closesocket(server_fd);
WSACleanup();
return 0;
}