2022-02-09 13:27:02 +00:00
|
|
|
#ifndef _SOCKET_HPP_
|
|
|
|
#define _SOCKET_HPP_
|
|
|
|
|
2022-02-10 07:40:58 +00:00
|
|
|
#include <winsock2.h>
|
|
|
|
#include <ws2tcpip.h>
|
2022-02-09 13:27:02 +00:00
|
|
|
#include <stdexcept>
|
|
|
|
#pragma comment(lib, "Ws2_32.lib")
|
|
|
|
|
|
|
|
class Socket
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
SOCKET serverSocket;
|
|
|
|
struct sockaddr_in SenderAddr;
|
|
|
|
int SenderAddrSize;
|
|
|
|
|
|
|
|
public:
|
|
|
|
Socket(short port)
|
|
|
|
{
|
|
|
|
int SenderAddrSize = sizeof(SenderAddr);
|
|
|
|
|
|
|
|
WSADATA wsaData;
|
|
|
|
int res = WSAStartup(MAKEWORD(2, 2), &wsaData);
|
|
|
|
if (res != NO_ERROR)
|
|
|
|
{
|
|
|
|
throw std::runtime_error("WSAStartup failed");
|
|
|
|
}
|
|
|
|
|
|
|
|
serverSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
|
|
|
if (serverSocket == INVALID_SOCKET)
|
|
|
|
{
|
|
|
|
throw std::runtime_error("socket creation failed: " + WSAGetLastError());
|
|
|
|
}
|
|
|
|
|
|
|
|
// Non blocking setting
|
|
|
|
u_long val = 1; // 0: blocking, 1: non-blocking
|
|
|
|
ioctlsocket(serverSocket, FIONBIO, &val);
|
|
|
|
|
|
|
|
// Bind the socket to any address and the specified port.
|
|
|
|
struct sockaddr_in serverAddr;
|
|
|
|
serverAddr.sin_family = AF_INET;
|
|
|
|
serverAddr.sin_port = htons(port);
|
|
|
|
serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);
|
|
|
|
|
|
|
|
if (bind(serverSocket, (SOCKADDR *)&serverAddr, sizeof(serverAddr)))
|
|
|
|
{
|
|
|
|
throw std::runtime_error("binding socket failed: " + WSAGetLastError());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
~Socket()
|
|
|
|
{
|
|
|
|
closesocket(serverSocket);
|
|
|
|
WSACleanup();
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string receive()
|
|
|
|
{
|
|
|
|
int bytes_received;
|
|
|
|
char serverBuf[1025];
|
|
|
|
int serverBufLen = 1024;
|
|
|
|
|
|
|
|
bytes_received = recvfrom(serverSocket, serverBuf, serverBufLen, 0 /* no flags*/, (SOCKADDR *)&SenderAddr, &SenderAddrSize);
|
|
|
|
if (bytes_received == SOCKET_ERROR)
|
|
|
|
{
|
|
|
|
throw std::runtime_error("receive failed: " + WSAGetLastError());
|
|
|
|
}
|
|
|
|
|
|
|
|
serverBuf[bytes_received] = '\0';
|
|
|
|
|
|
|
|
std::string msg(serverBuf);
|
|
|
|
|
|
|
|
return msg;
|
|
|
|
}
|
|
|
|
|
|
|
|
void send(std::string msg)
|
|
|
|
{
|
2022-02-09 14:10:58 +00:00
|
|
|
if (!has_end_point())
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-02-09 13:27:02 +00:00
|
|
|
if (msg.length() > 1024)
|
|
|
|
{
|
|
|
|
throw std::runtime_error("msg is too long: " + msg.length());
|
|
|
|
}
|
|
|
|
|
|
|
|
int sendResult = sendto(serverSocket, (const char *)&msg, msg.length(), 0, (SOCKADDR *)&SenderAddr, SenderAddrSize);
|
|
|
|
if (sendResult == SOCKET_ERROR)
|
|
|
|
{
|
|
|
|
throw std::runtime_error("send failed: " + WSAGetLastError());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2022-02-09 14:10:58 +00:00
|
|
|
bool has_end_point()
|
|
|
|
{
|
|
|
|
return SenderAddr.sin_port != 0;
|
|
|
|
}
|
2022-02-09 13:27:02 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
#endif // _SOCKET_HPP_
|