Supermodel/Src/Network/UDPReceive.cpp

90 lines
1.9 KiB
C++
Raw Normal View History

#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<65>s port number
serverInfo.sin_addr.s_addr = INADDR_ANY; // set server<65>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;
}
}