102 lines
2.8 KiB
C++
102 lines
2.8 KiB
C++
#include "WindowsMQTT.h"
|
|
|
|
#if defined(_WIN32) || defined(_WIN64)
|
|
|
|
#include <winsock2.h>
|
|
#include <ws2tcpip.h>
|
|
|
|
#include <chrono>
|
|
#include <thread>
|
|
|
|
namespace RoboidControl {
|
|
|
|
MQTTParticipant::MQTTParticipant(const char* remoteIpAddress, int port)
|
|
: MQTTParticipantBase(remoteIpAddress, port) {
|
|
SetupTCP();
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
|
send_mqtt_connect("RoboidControl");
|
|
sendSubscribe("domoticz/out");
|
|
}
|
|
|
|
void MQTTParticipant::SetupTCP() {
|
|
// Initialize Winsock
|
|
WSADATA wsaData;
|
|
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
|
|
std::cerr << "WSAStartup failed: " << std::endl;
|
|
return;
|
|
}
|
|
|
|
// Create a TCP socket
|
|
this->sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
|
if (sock == INVALID_SOCKET) {
|
|
std::cerr << "TCP Socket creation failed: " << WSAGetLastError()
|
|
<< std::endl;
|
|
WSACleanup();
|
|
return;
|
|
}
|
|
|
|
// Define the server address
|
|
memset(&this->remote_addr, 0, sizeof(this->remote_addr));
|
|
this->remote_addr.sin_family = AF_INET;
|
|
this->remote_addr.sin_port = htons((u_short)this->remoteSite->port);
|
|
if (inet_pton(AF_INET, this->remoteSite->ipAddress, &this->remote_addr.sin_addr) <= 0) {
|
|
std::cerr << "Invalid address" << std::endl;
|
|
closesocket(sock);
|
|
WSACleanup();
|
|
return;
|
|
}
|
|
|
|
// Connect to the server
|
|
if (connect(sock, (sockaddr*)&this->remote_addr, sizeof(this->remote_addr)) ==
|
|
SOCKET_ERROR) {
|
|
std::cerr << "Connection failed: " << WSAGetLastError() << std::endl;
|
|
closesocket(sock);
|
|
WSACleanup();
|
|
return;
|
|
}
|
|
|
|
// Set the socket to non-blocking mode
|
|
u_long mode = 1; // 1 to enable non-blocking socket
|
|
if (ioctlsocket(sock, FIONBIO, &mode) != NO_ERROR) {
|
|
std::cerr << "Failed to set non-blocking mode: " << WSAGetLastError()
|
|
<< std::endl;
|
|
closesocket(sock);
|
|
WSACleanup();
|
|
return;
|
|
}
|
|
}
|
|
|
|
int MQTTParticipant::ReceiveTCP() {
|
|
int bytesReceived = recv(sock, buffer, sizeof(buffer) - 1, 0);
|
|
if (bytesReceived > 0) {
|
|
buffer[bytesReceived] = '\0'; // Null-terminate the received data
|
|
std::cout << "Received: " << buffer << std::endl;
|
|
return bytesReceived;
|
|
} else if (bytesReceived == 0) {
|
|
// Connection has been gracefully closed
|
|
std::cout << "Connection closed by the server." << std::endl;
|
|
return 0;
|
|
} else {
|
|
int error = WSAGetLastError();
|
|
if (error == WSAEWOULDBLOCK) {
|
|
// No data available, continue with other tasks
|
|
//std::cout << "No data available, continuing..." << std::endl;
|
|
// You can add a sleep or other logic here to avoid busy waiting
|
|
} else {
|
|
std::cerr << "Receive failed: " << error << std::endl;
|
|
}
|
|
return 0;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void MQTTParticipant::SendTCP(int bufferSize) {
|
|
#if defined(_WIN32) || defined(_WIN64)
|
|
send(sock, this->buffer, bufferSize, 0);
|
|
#endif
|
|
}
|
|
|
|
} // namespace RoboidControl
|
|
|
|
#endif |