112 lines
2.7 KiB
C++
112 lines
2.7 KiB
C++
#include "udp-driver.h"
|
|
#include <iostream>
|
|
#include <cstring>
|
|
|
|
UDPSocket::UDPSocket(const std::string& ip, uint16_t port) {
|
|
#ifdef _WIN32
|
|
sockfd = INVALID_SOCKET;
|
|
#else
|
|
sockfd = -1;
|
|
#endif
|
|
|
|
if (!initialize()) {
|
|
return;
|
|
}
|
|
|
|
// Создание сокета
|
|
#ifdef _WIN32
|
|
sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
|
if (sockfd == INVALID_SOCKET) {
|
|
std::cerr << "Socket creation failed: " << WSAGetLastError() << std::endl;
|
|
return;
|
|
}
|
|
#else
|
|
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
|
|
if (sockfd < 0) {
|
|
std::cerr << "Socket creation failed" << std::endl;
|
|
return;
|
|
}
|
|
#endif
|
|
|
|
// Настройка адреса назначения
|
|
memset(&dest_addr, 0, sizeof(dest_addr));
|
|
dest_addr.sin_family = AF_INET;
|
|
dest_addr.sin_port = htons(port);
|
|
|
|
#ifdef _WIN32
|
|
dest_addr.sin_addr.s_addr = inet_addr(ip.c_str());
|
|
if (dest_addr.sin_addr.s_addr == INADDR_NONE) {
|
|
std::cerr << "Invalid address: " << ip << std::endl;
|
|
closesocket(sockfd);
|
|
sockfd = INVALID_SOCKET;
|
|
}
|
|
#else
|
|
if (inet_pton(AF_INET, ip.c_str(), &dest_addr.sin_addr) <= 0) {
|
|
std::cerr << "Invalid address: " << ip << std::endl;
|
|
close(sockfd);
|
|
sockfd = -1;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
bool UDPSocket::initialize() {
|
|
#ifdef _WIN32
|
|
// Инициализация Winsock
|
|
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
|
|
std::cerr << "WSAStartup failed: " << WSAGetLastError() << std::endl;
|
|
return false;
|
|
}
|
|
#endif
|
|
return true;
|
|
}
|
|
|
|
UDPSocket::~UDPSocket() {
|
|
#ifdef _WIN32
|
|
if (sockfd != INVALID_SOCKET) {
|
|
closesocket(sockfd);
|
|
}
|
|
WSACleanup();
|
|
#else
|
|
if (sockfd >= 0) {
|
|
close(sockfd);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
bool UDPSocket::sendFrame(const std::vector<uint16_t>& data) {
|
|
#ifdef _WIN32
|
|
if (sockfd == INVALID_SOCKET) return false;
|
|
#else
|
|
if (sockfd < 0) return false;
|
|
#endif
|
|
|
|
if (data.empty()) return false;
|
|
|
|
// Отправка данных
|
|
#ifdef _WIN32
|
|
int result = sendto(sockfd,
|
|
reinterpret_cast<const char*>(data.data()),
|
|
data.size() * sizeof(uint16_t),
|
|
0,
|
|
(sockaddr*)&dest_addr,
|
|
sizeof(dest_addr));
|
|
if (result == SOCKET_ERROR) {
|
|
std::cerr << "Send failed: " << WSAGetLastError() << std::endl;
|
|
return false;
|
|
}
|
|
#else
|
|
ssize_t result = sendto(sockfd,
|
|
data.data(),
|
|
data.size() * sizeof(uint16_t),
|
|
0,
|
|
(sockaddr*)&dest_addr,
|
|
sizeof(dest_addr));
|
|
if (result < 0) {
|
|
std::cerr << "Send failed" << std::endl;
|
|
return false;
|
|
}
|
|
#endif
|
|
|
|
return true;
|
|
}
|