mirror of
https://github.com/RetroDECK/Supermodel.git
synced 2024-11-29 17:15:40 +00:00
90 lines
1.9 KiB
C++
90 lines
1.9 KiB
C++
#include <winsock2.h>
|
||
#include <windows.h>
|
||
#include "UDPReceive.h"
|
||
#include "UDPPacket.h"
|
||
|
||
namespace SMUDP
|
||
{
|
||
|
||
UDPReceive::UDPReceive()
|
||
{
|
||
m_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); // create the socket
|
||
m_readEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||
|
||
WSAEventSelect(m_socket, m_readEvent, FD_READ);
|
||
}
|
||
|
||
UDPReceive::~UDPReceive()
|
||
{
|
||
closesocket(m_socket);
|
||
CloseHandle(m_readEvent);
|
||
}
|
||
|
||
bool UDPReceive::Bind(UINT16 port)
|
||
{
|
||
//===========================
|
||
int err;
|
||
SOCKADDR_IN serverInfo = {};
|
||
//===========================
|
||
|
||
serverInfo.sin_family = AF_INET; // address family Internet
|
||
serverInfo.sin_port = htons(port); // set server’s port number
|
||
serverInfo.sin_addr.s_addr = INADDR_ANY; // set server’s IP
|
||
|
||
err = bind(m_socket, (LPSOCKADDR)&serverInfo, sizeof(struct sockaddr));
|
||
|
||
return (err == 0);
|
||
}
|
||
|
||
std::vector<UINT8>& UDPReceive::ReadData(int timeout)
|
||
{
|
||
m_data.clear();
|
||
|
||
while (true) {
|
||
|
||
//========
|
||
DWORD res;
|
||
//========
|
||
|
||
res = WaitForSingleObject(m_readEvent, timeout);
|
||
|
||
if (res == WAIT_OBJECT_0) {
|
||
|
||
//=========================
|
||
int result;
|
||
int slen;
|
||
sockaddr_in si_other;
|
||
Packet packet;
|
||
//=========================
|
||
|
||
slen = sizeof(sockaddr_in);
|
||
|
||
result = recvfrom(m_socket, packet, sizeof(packet), 0, (struct sockaddr *) &si_other, &slen);
|
||
|
||
if (result == SOCKET_ERROR) {
|
||
auto error = WSAGetLastError(); // clear error code
|
||
m_data.clear();
|
||
break;
|
||
}
|
||
|
||
// copy data to array
|
||
m_data.insert(m_data.end(), packet.data, packet.data + packet.length);
|
||
|
||
PacketReply r = 1;
|
||
result = sendto(m_socket, &r, sizeof(r), 0, (struct sockaddr *)&si_other, sizeof(SOCKADDR_IN));
|
||
|
||
if (packet.currentID + 1 == packet.totalIDs) {
|
||
break; // reached the end
|
||
}
|
||
}
|
||
else {
|
||
m_data.clear(); // reset any memory because we have failed
|
||
break; // timeout
|
||
}
|
||
}
|
||
|
||
return m_data;
|
||
}
|
||
|
||
}
|