我正在尝试使用winsock2实现一个简单的TCP服务器应用程序。为此,我有一个接受连接(TcpServer
)的类和一个处理连接的类(TcpListener
)。为此,这些对象需要共享SOCKET
,whis定义为UINT_PTR
。为了安全地分享这个,shared_ptr
似乎是要走的路。不幸的是,shared_ptr
似乎应该包含struct
或class
,因此我的实现如下。
struct SafeSocket_
{
SOCKET Socket;
SafeSocket_(SOCKET socket)
: Socket(socket)
{}
~SafeSocket_()
{
closesocket(Socket);
std::cout << "destroyed SafeSocket_" << std::endl;
}
};
typedef std::shared_ptr<SafeSocket_> SafeSocket;
要创建/接受新套接字,我使用以下可怕的代码。更糟糕的是,我需要在整个地方使用ClientSocket->Socket
。
SafeSocket ClientSocket = SafeSocket(new SafeSocket_(accept(ListenSocket, NULL, NULL)));
除了使用一个漂亮的包装库之外,还有一种更好的方法来处理它。
注意:我知道有很好的包装库喜欢来自boost的asio,但我只是搞乱了解一些C ++基础知识。
答案 0 :(得分:0)
基本问题是UINT_PTR
不是不透明的指针。这是一个整数。如果它是typedef struct __socket SOCKET;
,那么你可以写std::shared_ptr<decltype(*SOCKET{})>
,坚持使用自定义删除器来调用close_socket,然后你就会笑。
有许多可能的方法:
SafeSocket
成为包含shared_ptr且具有socket
成员函数的类。然后你就到处写ClientSocket.socket()
。SafeSocket
版本的套接字函数,它提供了实际的socket参数。因此,您需要read( ClientSocket.Socket, ...)
而不是ClientSocket.read(...)
。SafeSocket
作为typedef,但将其他功能放在SafeSocket_
中,以便您编写ClientSocket->read(...)
我认为我最喜欢中间解决方案。