#ifndef _SOCKET_HPP_ #define _SOCKET_HPP_ #include #include #include #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) { if (!has_end_point()) { return; } 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: bool has_end_point() { return SenderAddr.sin_port != 0; } }; #endif // _SOCKET_HPP_