Posix support
This commit is contained in:
parent
18d6ea762c
commit
f591d34d97
@ -5,6 +5,7 @@
|
|||||||
#define BUF_SIZE 1024
|
#define BUF_SIZE 1024
|
||||||
|
|
||||||
#include "UdpArduino.h"
|
#include "UdpArduino.h"
|
||||||
|
#include "UdpPosix.h"
|
||||||
#include "UdpWindows.h"
|
#include "UdpWindows.h"
|
||||||
|
|
||||||
#if defined(_WIN32) || defined(_WIN64)
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
@ -47,6 +48,9 @@ void Passer::Control::Participant::SetupUDP(int localPort,
|
|||||||
#if defined(_WIN32) || defined(_WIN64)
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
UdpWindows *thisWindows = static_cast<UdpWindows *>(this);
|
UdpWindows *thisWindows = static_cast<UdpWindows *>(this);
|
||||||
thisWindows->Setup(localPort, remoteIpAddress, remotePort);
|
thisWindows->Setup(localPort, remoteIpAddress, remotePort);
|
||||||
|
#elif defined(__unix__) || defined(__APPLE__)
|
||||||
|
UdpPosix *thisPosix = static_cast<UdpPosix *>(this);
|
||||||
|
thisPosix->Setup(localPort, remoteIpAddress, remotePort);
|
||||||
#elif defined(ARDUINO)
|
#elif defined(ARDUINO)
|
||||||
UdpArduino *thisArduino = static_cast<UdpArduino *>(this);
|
UdpArduino *thisArduino = static_cast<UdpArduino *>(this);
|
||||||
thisArduino->Setup(localPort, remoteIpAddress, remotePort);
|
thisArduino->Setup(localPort, remoteIpAddress, remotePort);
|
||||||
@ -70,6 +74,9 @@ void Participant::ReceiveUDP() {
|
|||||||
#if defined(_WIN32) || defined(_WIN64)
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
UdpWindows *thisWindows = static_cast<UdpWindows *>(this);
|
UdpWindows *thisWindows = static_cast<UdpWindows *>(this);
|
||||||
thisWindows->Receive();
|
thisWindows->Receive();
|
||||||
|
#elif defined(__unix__) || defined(__APPLE__)
|
||||||
|
UdpPosix *thisPosix = static_cast<UdpPosix *>(this);
|
||||||
|
thisPosix->Receive();
|
||||||
#elif defined(ARDUINO)
|
#elif defined(ARDUINO)
|
||||||
UdpArduino *thisArduino = static_cast<UdpArduino *>(this);
|
UdpArduino *thisArduino = static_cast<UdpArduino *>(this);
|
||||||
thisArduino->Receive();
|
thisArduino->Receive();
|
||||||
@ -125,6 +132,9 @@ bool Participant::Send(IMessage *msg) {
|
|||||||
#if defined(_WIN32) || defined(_WIN64)
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
UdpWindows *thisWindows = static_cast<UdpWindows *>(this);
|
UdpWindows *thisWindows = static_cast<UdpWindows *>(this);
|
||||||
return thisWindows->Send(msg);
|
return thisWindows->Send(msg);
|
||||||
|
#elif defined(__unix__) || defined(__APPLE__)
|
||||||
|
UdpPosix *thisPosix = static_cast<UdpPosix *>(this);
|
||||||
|
return thisPosix->Send(msg);
|
||||||
#elif defined(ARDUINO)
|
#elif defined(ARDUINO)
|
||||||
UdpArduino *thisArduino = static_cast<UdpArduino *>(this);
|
UdpArduino *thisArduino = static_cast<UdpArduino *>(this);
|
||||||
return thisArduino->Send(msg);
|
return thisArduino->Send(msg);
|
||||||
@ -135,6 +145,9 @@ bool Participant::Publish(IMessage *msg) {
|
|||||||
#if defined(_WIN32) || defined(_WIN64)
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
UdpWindows *thisWindows = static_cast<UdpWindows *>(this);
|
UdpWindows *thisWindows = static_cast<UdpWindows *>(this);
|
||||||
return thisWindows->Publish(msg);
|
return thisWindows->Publish(msg);
|
||||||
|
#elif defined(__unix__) || defined(__APPLE__)
|
||||||
|
UdpPosix *thisPosix = static_cast<UdpPosix *>(this);
|
||||||
|
return thisPosix->Publish(msg);
|
||||||
#elif defined(ARDUINO)
|
#elif defined(ARDUINO)
|
||||||
UdpArduino *thisArduino = static_cast<UdpArduino *>(this);
|
UdpArduino *thisArduino = static_cast<UdpArduino *>(this);
|
||||||
return thisArduino->Publish(msg);
|
return thisArduino->Publish(msg);
|
||||||
|
207
UdpPosix.cpp
Normal file
207
UdpPosix.cpp
Normal file
@ -0,0 +1,207 @@
|
|||||||
|
#include "UdpPosix.h"
|
||||||
|
|
||||||
|
#if defined(__unix__) || defined(__APPLE__)
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <fcntl.h> // For fcntl
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace Passer {
|
||||||
|
namespace Control {
|
||||||
|
|
||||||
|
void UdpPosix::Setup(int localPort, const char *remoteIpAddress,
|
||||||
|
int remotePort) {
|
||||||
|
#if defined(__unix__) || defined(__APPLE__)
|
||||||
|
|
||||||
|
// Create a UDP socket
|
||||||
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
|
// Windows-specific Winsock initialization
|
||||||
|
WSADATA wsaData;
|
||||||
|
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
|
||||||
|
std::cerr << "WSAStartup failed" << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
|
this->sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||||
|
#elif defined(__unix__) || defined(__APPLE__)
|
||||||
|
this->sock = socket(AF_INET, SOCK_DGRAM, 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (this->sock < 0) {
|
||||||
|
std::cerr << "Error creating socket" << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the socket to non-blocking mode
|
||||||
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
|
u_long mode = 1; // 1 to enable non-blocking socket
|
||||||
|
ioctlsocket(this->sock, FIONBIO, &mode);
|
||||||
|
#elif defined(__unix__) || defined(__APPLE__)
|
||||||
|
int flags = fcntl(this->sock, F_GETFL, 0);
|
||||||
|
fcntl(this->sock, F_SETFL, flags | O_NONBLOCK);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (remotePort != 0) {
|
||||||
|
// Set up the address to send to
|
||||||
|
memset(&remote_addr, 0, sizeof(remote_addr));
|
||||||
|
remote_addr.sin_family = AF_INET;
|
||||||
|
remote_addr.sin_port = htons(remotePort);
|
||||||
|
if (inet_pton(AF_INET, remoteIpAddress, &remote_addr.sin_addr) <= 0) {
|
||||||
|
std::cerr << "Invalid address" << std::endl;
|
||||||
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
|
closesocket(sock);
|
||||||
|
WSACleanup();
|
||||||
|
#elif defined(__unix__) || defined(__APPLE__)
|
||||||
|
close(sock);
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up the receiving address
|
||||||
|
memset(&server_addr, 0, sizeof(server_addr));
|
||||||
|
server_addr.sin_family = AF_INET;
|
||||||
|
server_addr.sin_port = htons(localPort);
|
||||||
|
if (inet_pton(AF_INET, "0.0.0.0", &server_addr.sin_addr) <= 0) {
|
||||||
|
std::cerr << "Invalid address" << std::endl;
|
||||||
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
|
closesocket(sock);
|
||||||
|
WSACleanup();
|
||||||
|
#elif defined(__unix__) || defined(__APPLE__)
|
||||||
|
close(sock);
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bind the socket to the specified port
|
||||||
|
if (bind(this->sock, (const struct sockaddr *)&server_addr,
|
||||||
|
sizeof(server_addr)) < 0) {
|
||||||
|
std::cerr << "Bind failed" << std::endl;
|
||||||
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
|
closesocket(sock);
|
||||||
|
WSACleanup();
|
||||||
|
#elif defined(__unix__) || defined(__APPLE__)
|
||||||
|
close(sock);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void UdpPosix::Receive() {
|
||||||
|
#if defined(__unix__) || defined(__APPLE__)
|
||||||
|
// char ip_str[INET_ADDRSTRLEN];
|
||||||
|
// inet_ntop(AF_INET, &(server_addr.sin_addr), ip_str, INET_ADDRSTRLEN);
|
||||||
|
// std::cout << this->name << " Receive on " << ip_str << ":"
|
||||||
|
// << ntohs(server_addr.sin_port) << "\n";
|
||||||
|
|
||||||
|
sockaddr_in client_addr;
|
||||||
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
|
int len = sizeof(client_addr);
|
||||||
|
#elif defined(__unix__) || defined(__APPLE__)
|
||||||
|
socklen_t len = sizeof(client_addr);
|
||||||
|
#endif
|
||||||
|
int packetSize = recvfrom(this->sock, buffer, sizeof(buffer), 0,
|
||||||
|
(struct sockaddr *)&client_addr, &len);
|
||||||
|
// std::cout << "received data " << packetSize << "\n";
|
||||||
|
if (packetSize < 0) {
|
||||||
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
|
int error_code = WSAGetLastError(); // Get the error code on Windows
|
||||||
|
if (error_code != WSAEWOULDBLOCK)
|
||||||
|
std::cerr << "recvfrom failed with error: " << error_code << std::endl;
|
||||||
|
#else
|
||||||
|
// std::cerr << "recvfrom failed with error: " << packetSize << std::endl;
|
||||||
|
#endif
|
||||||
|
} else if (packetSize > 0) {
|
||||||
|
char sender_ipAddress[INET_ADDRSTRLEN];
|
||||||
|
inet_ntop(AF_INET, &(client_addr.sin_addr), sender_ipAddress,
|
||||||
|
INET_ADDRSTRLEN);
|
||||||
|
int sender_port = ntohs(client_addr.sin_port);
|
||||||
|
|
||||||
|
Participant *remoteParticipant =
|
||||||
|
this->GetParticipant(sender_ipAddress, sender_port);
|
||||||
|
if (remoteParticipant == nullptr) {
|
||||||
|
remoteParticipant = this->AddParticipant(sender_ipAddress, sender_port);
|
||||||
|
std::cout << "New sender " << sender_ipAddress << ":" << sender_port
|
||||||
|
<< "\n";
|
||||||
|
std::cout << "New remote participant " << remoteParticipant->ipAddress
|
||||||
|
<< ":" << remoteParticipant->port << " "
|
||||||
|
<< (int)remoteParticipant->networkId << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
ReceiveData(packetSize, remoteParticipant);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UdpPosix::Send(
|
||||||
|
IMessage *msg) { // Send the message to the specified address and port
|
||||||
|
#if defined(__unix__) || defined(__APPLE__)
|
||||||
|
int bufferSize = msg->Serialize(this->buffer);
|
||||||
|
// std::cout << "buffer size " << bufferSize << "\n";
|
||||||
|
if (bufferSize <= 0)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
char ip_str[INET_ADDRSTRLEN];
|
||||||
|
inet_ntop(AF_INET, &(remote_addr.sin_addr), ip_str, INET_ADDRSTRLEN);
|
||||||
|
std::cout << "Send to " << ip_str << ":" << ntohs(remote_addr.sin_port)
|
||||||
|
<< "\n";
|
||||||
|
int sent_bytes = sendto(sock, this->buffer, bufferSize, 0,
|
||||||
|
(struct sockaddr *)&remote_addr, sizeof(remote_addr));
|
||||||
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
|
if (sent_bytes <= SOCKET_ERROR) {
|
||||||
|
int error_code = WSAGetLastError(); // Get the error code on Windows
|
||||||
|
std::cerr << "sendto failed with error: " << error_code << std::endl;
|
||||||
|
closesocket(sock);
|
||||||
|
WSACleanup();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#elif defined(__unix__) || defined(__APPLE__)
|
||||||
|
if (sent_bytes < 0) {
|
||||||
|
std::cerr << "sendto failed with error: " << sent_bytes << std::endl;
|
||||||
|
close(sock);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UdpPosix::Publish(IMessage *msg) {
|
||||||
|
#if defined(__unix__) || defined(__APPLE__)
|
||||||
|
int bufferSize = msg->Serialize(this->buffer);
|
||||||
|
if (bufferSize <= 0)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
char ip_str[INET_ADDRSTRLEN];
|
||||||
|
inet_ntop(AF_INET, &(broadcast_addr.sin_addr), ip_str, INET_ADDRSTRLEN);
|
||||||
|
std::cout << "Publish to " << ip_str << ":" << ntohs(broadcast_addr.sin_port)
|
||||||
|
<< "\n";
|
||||||
|
int sent_bytes =
|
||||||
|
sendto(sock, this->buffer, bufferSize, 0,
|
||||||
|
(struct sockaddr *)&broadcast_addr, sizeof(broadcast_addr));
|
||||||
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
|
if (sent_bytes <= SOCKET_ERROR) {
|
||||||
|
int error_code = WSAGetLastError(); // Get the error code on Windows
|
||||||
|
std::cerr << "sendto failed with error: " << error_code << std::endl;
|
||||||
|
closesocket(sock);
|
||||||
|
WSACleanup();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#elif defined(__unix__) || defined(__APPLE__)
|
||||||
|
if (sent_bytes < 0) {
|
||||||
|
std::cerr << "sendto failed with error: " << sent_bytes << std::endl;
|
||||||
|
close(sock);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Control
|
||||||
|
} // namespace Passer
|
17
UdpPosix.h
Normal file
17
UdpPosix.h
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Participant.h"
|
||||||
|
|
||||||
|
namespace Passer {
|
||||||
|
namespace Control {
|
||||||
|
|
||||||
|
class UdpPosix : public Participant {
|
||||||
|
public:
|
||||||
|
void Setup(int localPort, const char *remoteIpAddress, int remotePort);
|
||||||
|
void Receive();
|
||||||
|
bool Send(IMessage *msg);
|
||||||
|
bool Publish(IMessage *msg);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Control
|
||||||
|
} // namespace Passer
|
Loading…
x
Reference in New Issue
Block a user