1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
|
#ifndef _CFNETWORKING_H_
#define _CFNETWORKING_H_
#include "Core.h"
#include "Error.h"
#include <WinSock2.h>
class CF::Networking::System
{
public:
System() {}
// Either make this return bool, or don't bother driving success.
// Another option is to throw something if an error occurs like you do everywhere else
void Init()
{
bool success = false;
WSADATA wsaData = {};
success = (WSAStartup(MAKEWORD(2, 2), &wsaData) == NO_ERROR);
}
void Cleanup()
{
WSACleanup();
}
~System()
{
Cleanup();
}
private:
};
class CF::Networking::Socket
{
public:
Socket(unsigned short port)
{
Open(port);
}
void Open(unsigned short port)
{
this->port = port;
handle = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
DWORD nonBlock = 1;
if(handle < 0) // maybe <= instead?
{
// You could use: (__FUNCTION__ "- Failure getting handle to socket.") if your compiler supports it.
throw CF::Error("CF::Networking::Socket::Socket() - Failure getting handle to socket.");
}
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(port);
if(bind(handle, (const sockaddr*)&address, sizeof(sockaddr_in)) < 0)
{
throw CF::Error("CF::Networking::Socket::Socket::() - Failure binding socket.");
}
if (ioctlsocket(handle, FIONBIO, &nonBlock) != 0)
{
throw CF::Error("CF::Networking::Socket::Socket::() - Failure setting non-binding socket.");
}
}
// Not sure what destArrd should contain based on the type.
// Maybe you want to make an IPAddress class which can be constructed in a few ways.
template<class T>
void Send(const char* destAddr, T* packet, size_t numElem = 1)
{
if(numElem == 0) numElem = 1;
size_t sentBytes = 0;
sockaddr_in sAddr;
const char* c_packet = reinterpret_cast<const char*>(packet);
sAddr.sin_family = AF_INET;
sAddr.sin_addr.S_un.S_addr = inet_addr(destAddr);
sAddr.sin_port = port;
sentBytes = sendto(handle, c_packet, (int)size, 0, (const sockaddr*)&sAddr, sizeof(sAddr));
if(sentBytes != size)
throw CF::Error("CF::Networking::Socket::Send() - Entire packet was not sent.");
}
template<class T>
void Recv(T* buffer, size_t numElem = 1)
{
if(numElem == 0) numElem = 1;
sockaddr_in sAddr;
sAddr.sin_family = AF_INET;
sAddr.sin_addr.S_un.S_addr = inet_addr(destAddr);
sAddr.sin_port = port;
if(recvfrom(handle, (char*)buffer, sizeof(T) * numElem, 0, (sockaddr*)&sAddr, sizeof(sockaddr_in)) == SOCKET_ERROR)
{
throw CF::Error("CF::Networking::Socket::Recv() - recvfrom() failed.");
}
}
void Close()
{
closesocket(handle);
handle = 0;
}
~Socket()
{
Close();
}
private:
CF::UintPtr handle;
sockaddr_in address;
unsigned short port;
};
#endif//_CFNETWORKING_H_
| |