To realize the raii idiom for the type SOCKET
, I have created a wrapper. The wrapper calls connect
in the constructor and closesocket
in its destructor. A std::map
holds all used sockets. Unfortunatelly inserting a new socket into the container calls the destructor of a temporary and, in fact, closes the just opened socket. Is there a common way to overcome this?
Here is the code:
#include <iostream>
#include <stdexcept>
#include <map>
#include <winsock2.h>
struct Socket {
SOCKET mSock;
Socket() : mSock(INVALID_SOCKET) {}
Socket(std::string ip, int port);
~Socket();
};
Socket::Socket(std::string ip, int port) {
mSock = socket(AF_INET, SOCK_STREAM, 0);
if (mSock == INVALID_SOCKET)
throw std::runtime_error("socket()");
SOCKADDR_IN addr = {0};
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = inet_addr(ip.c_str());
if (connect(mSock, reinterpret_cast<SOCKADDR*>(&addr), sizeof(addr))
== SOCKET_ERROR)
throw std::runtime_error("connect()");
std::cout << mSock << " connected" << std::endl;
}
Socket::~Socket() {
if (mSock != INVALID_SOCKET) {
closesocket(mSock);
std::cout << mSock << " closed" << std::endl;
}
}
int main() {
WSADATA wsa;
WSAStartup(MAKEWORD(2, 0), &wsa);
std::map<int, Socket> outbound;
// calls constructur but also destructor
outbound[0] = Socket("192.168.128.125", 4023);
WSACleanup();
return 0;
}
And the Output is:
1952 connected
1952 closed
1952 closed