Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Modified copypasta thrown into a class that might have a usecase for later...
// Shamelessly stolen from https://msdn.microsoft.com/en-us/library/windows/desktop/ms737591(v=vs.85).aspx
#define WIN32_LEAN_AND_MEAN
// Need to link with Ws2_32.lib, Mswsock.lib, and Advapi32.lib
#pragma comment (lib, "Ws2_32.lib")
#pragma comment (lib, "Mswsock.lib")
#pragma comment (lib, "AdvApi32.lib")
template <size_t recvbuflen>
class Socket
{
WSADATA wsaData;
SOCKET ConnectSocket;
struct addrinfo *result, *ptr, hints;
std::array<char, recvbuflen> recvbuf;
bool initialized, is_good;
int iResult;
public:
Socket(std::stringstream& output, const std::string& serverName, const std::string& port)
: ConnectSocket(INVALID_SOCKET),
result(NULL), ptr(NULL),
initialized(false), is_good(false),
iResult(0)
{
recvbuf.fill(0);
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
output << "WSAStartup failed with error: " << iResult << "\n";
return;
}
initialized = true;
ZeroMemory( &hints, sizeof(hints) );
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
iResult = getaddrinfo(serverName.c_str(), port.c_str(), &hints, &result);
if (iResult != 0) {
output << "getaddrinfo failed with error code: " << iResult << "\n";
return;
}
is_good = true;
}
~Socket(void)
{
kill();
}
void set_recvbuffer(const char* buffer)
{
recvbuf.fill(0);
size_t length = std::min(strlen(buffer), recvbuflen);
memcpy(&recvbuf[0], &buffer[0], length * sizeof(buffer[0]));
}
void send_msg(const char* in)
{
send(ConnectSocket, in, (int)strlen(in), 0);
}
void kill(void)
{
if (initialized) {
WSACleanup();
if (result) {
freeaddrinfo(result);
result = NULL;
}
initialized = false;
}
is_good = false;
}
bool good(void) const
{
return is_good;
}
bool try_connect(std::stringstream& output)
{
if (!result) {
goto fail;
}
// Attempt to connect to an address until one succeeds
for(ptr = result; ptr != NULL; ptr = ptr->ai_next) {
// Create a SOCKET for connecting to server
ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
if (ConnectSocket == INVALID_SOCKET) {
output << "socket failed with error: " << WSAGetLastError() << "\n";
goto fail;
}
// Connect to server.
iResult = connect(ConnectSocket, ptr->ai_addr, (int) ptr->ai_addrlen);
if (iResult == SOCKET_ERROR) {
closesocket(ConnectSocket);
ConnectSocket = INVALID_SOCKET;
continue;
}
break;
}
if (ConnectSocket == INVALID_SOCKET) {
output << "Unable to connect to server!\n";
goto fail;
}
return true;
fail:
kill();
return false;
}
int last_error(void) const
{
return iResult;
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment