first commit
This commit is contained in:
210
报文模拟解析/vdes_simulator.c
Normal file
210
报文模拟解析/vdes_simulator.c
Normal file
@@ -0,0 +1,210 @@
|
||||
#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;
|
||||
}
|
||||
Reference in New Issue
Block a user