Чтобы реализовать идиому raii для типа SOCKET
, я создали обертку. Оболочка вызывает connect
в конструкторе и closesocket
в своем деструкторе. std::map
содержит все используемые сокеты. К сожалению, вставка нового сокета в контейнер вызывает деструктор временного и, по сути, закрывает только что открытый сокет. Есть ли общий способ преодолеть это?
Вот код:
#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;
}
И вывод:
1952 connected
1952 closed
1952 closed
Socket
. Если подумать, нет смысла копировать сокет. - person syam   schedule 25.07.2013outbound[0].connect("192.168.128.125", ...)
, если бы был реализован методconnect
. И, как сказал syam, сделайте конструктор копирования/оператор присваивания закрытым, чтобы предотвратить замеченную вами ошибку. - person Rollie   schedule 25.07.2013