diff --git a/udp_receiver/main.cpp b/udp_receiver/main.cpp new file mode 100644 index 0000000..330f1fe --- /dev/null +++ b/udp_receiver/main.cpp @@ -0,0 +1,230 @@ +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// +#include + +#pragma comment(lib, "ws2_32.lib") +#define PORT 19903 +using namespace std; + +typedef struct { + uint32_t eventid; + int32_t data[4]; +} iflytop_xsync_event_report_packet_t; + +static std::ofstream* logfile; + +/** + * @brief 获取 年月日时分秒:毫秒 + * + * @return string + */ +static const char* gettime_str() { + time_t t = time(0); + static char tmp[64]; + strftime(tmp, sizeof(tmp), "%Y-%m-%d %H:%M:%S", localtime(&t)); + struct tm* tt = localtime(&t); + // sprintf(tmp, "%s:%03d", tmp, GetTickCount() % 1000); + return tmp; +} + +static string getlogfilename() { + time_t t = time(0); + char tmp[64]; + strftime(tmp, sizeof(tmp), "%Y%m%d_%H%M%S.txt", localtime(&t)); + return tmp; +} + +/** + * @brief 写日志到文件中 + */ +bool log_file_init() { + // 创建日志文件 + logfile = new ofstream(getlogfilename(), ios::app); + if (logfile == NULL) { + printf("创建日志文件失败\n"); + return false; + } + return true; +} + +void log(const char* fmt, ...) { + char buf[1024] = {0}; + va_list args; + va_start(args, fmt); + vsprintf(buf, fmt, args); + va_end(args); + cout << buf; +} + +void logd(const char* fmt, ...) { + char buf[1024] = {0}; + va_list args; + va_start(args, fmt); + vsprintf(buf, fmt, args); + va_end(args); + if (logfile) { + *logfile << buf; + logfile->flush(); + } + cout << buf; +} + +#define LOGD(fmt, ...) logd("[%s] INFO : " fmt "\n", gettime_str(), ##__VA_ARGS__); + +int64_t gettime() { + auto currentTime = std::chrono::system_clock::now(); + return currentTime.time_since_epoch().count() / 1000000; +} +typedef struct { + uint32_t tc0; + uint32_t tc1; + uint32_t subframe; +} Timecode64_t; + +typedef struct { + uint8_t hour; + uint8_t minute; + uint8_t second; + uint8_t frame; + uint8_t subframe; +} XsyncTimecode_t; + +XsyncTimecode_t timecode64ToXsyncTimeCode(Timecode64_t tc64) { + uint8_t frameuints = tc64.tc0 & 0x0f; + uint8_t frame10s = (tc64.tc0 >> 8) & 0x3; + uint8_t seconduints = (tc64.tc0 >> 16) & 0x0f; + uint8_t second10s = (tc64.tc0 >> 24) & 0x07; + + uint8_t minuteuints = tc64.tc1 & 0x0f; + uint8_t minute10s = (tc64.tc1 >> 8) & 0x07; + uint8_t houruints = (tc64.tc1 >> 16) & 0x0f; + uint8_t hour10s = (tc64.tc1 >> 24) & 0x03; + + XsyncTimecode_t timecode; + timecode.hour = hour10s * 10 + houruints; + timecode.minute = minute10s * 10 + minuteuints; + timecode.second = second10s * 10 + seconduints; + timecode.frame = frame10s * 10 + frameuints; + timecode.subframe = tc64.subframe; + return timecode; +} +int main(int argc, char* argv[]) { + // 初始化网络环境 + log_file_init(); + WSADATA wsa; + if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0) { + LOGD("WSAStartup failed"); + return -1; + } + + // 建立一个UDP的socket + SOCKET sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (sock == SOCKET_ERROR) { + LOGD("create socket failed"); + return -1; + } + + // 绑定地址信息 + sockaddr_in serverAddr; + serverAddr.sin_family = AF_INET; + serverAddr.sin_port = htons(PORT); + serverAddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY); + + int ret = ::bind(sock, (sockaddr*)&serverAddr, sizeof(sockaddr)); + if (ret != 0) { + LOGD("bind failed"); + return -1; + } + + char buf[512]; + + while (TRUE) { + memset(buf, 0, 512); + sockaddr_in clientAddr; + memset(&clientAddr, 0, sizeof(sockaddr_in)); + int clientAddrLen = sizeof(sockaddr); + // 接收客户端发来的数据 + int ret = recvfrom(sock, buf, 512, 0, (sockaddr*)&clientAddr, &clientAddrLen); + + iflytop_xsync_event_report_packet_t* packet = (iflytop_xsync_event_report_packet_t*)buf; + + uint32_t stm32_ticket = packet->data[3]; + uint32_t stm32_send_delay = packet->data[4]; + + Timecode64_t tc64; + tc64.tc0 = packet->data[0]; + tc64.tc1 = packet->data[1]; + tc64.subframe = packet->data[2]; + XsyncTimecode_t timecode = timecode64ToXsyncTimeCode(tc64); + + static int64_t lastrxticket; + static uint32_t laststm32ticket = 0; + static int32_t et1 = 0; + static int32_t et2 = 0; + static int32_t et3 = 0; + static int32_t et4 = 0; + static Timecode64_t lasttimecode64; + static int32_t lastdifftime = 0; + static int32_t lastdiffstm32; + int64_t nowticket = gettime(); + int64_t difftime = nowticket - lastrxticket; + int64_t diffstm32 = stm32_ticket - laststm32ticket; + static int32_t totalPacketNum = 0; + totalPacketNum++; + + { + if (abs(difftime - lastdifftime) > 4) { + et1++; + LOGD("exception_1 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); + } + + if (abs(diffstm32 - lastdiffstm32) > 2) { + et2++; + LOGD("exception_2 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); + } + + if (stm32_send_delay > 1) { + et3++; + LOGD("exception_3 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); + } + + if (memcmp(&lasttimecode64, &tc64, sizeof(Timecode64_t)) == 0) { + et4++; + LOGD("exception_4 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); + } + + LOGD("pcticket:%ld(%10d) tc:%2d:%2d:%2d:%2d:%2d stm32ticket:%10d(%10d) stm32_send_delay:%d et:(%d %d %d %d)/%d", nowticket, difftime, // + timecode.hour, timecode.minute, timecode.second, timecode.frame, timecode.subframe, // + stm32_ticket, diffstm32, stm32_send_delay, // + et1 / 2, et2, et3, et4,totalPacketNum); + } + + lasttimecode64 = tc64; + + // + lastrxticket = nowticket; + laststm32ticket = stm32_ticket; + lastdifftime = difftime; + lastdiffstm32 = diffstm32; + + // 发一个数据包返回给客户 + } + return 0; +} \ No newline at end of file