2015-12-13 38 views
1

我試圖使用winsock2實現簡單的TCP服務器應用程序。爲此,我有一個接受連接的類(TcpServer)和一個處理連接的類(TcpListener)。爲此目的,這些物體需要共享SOCKET,whis被定義爲UINT_PTR。爲了安全地分享這個shared_ptr似乎是要走的路。不幸的是,shared_ptr似乎應該包裝structclass,因此我的實施如下。將不透明指針包裝在shared_ptr中

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

基本問題是UINT_PTR不是一個不透明的指針。這是一個整數。如果它是typedef struct __socket SOCKET;,那麼你可以只寫std::shared_ptr<decltype(*SOCKET{})>,在自定義刪除程序中調用close_socket,你會笑。

有許多可能的方法:

  • 製作SafeSocket是包含shared_ptr的一類,並且具有socket成員函數。然後你在那裏寫ClientSocket.socket()
  • 如上所述,但給出SafeSocket版本的套接字函數,並且它提供了實際的套接字參數。因此,您可以編寫ClientSocket.read(...)而不是read(ClientSocket.Socket, ...)
  • 恢復到SafeSocket作爲一個typedef,而是把更多的功能SafeSocket_,所以你寫ClientSocket->read(...)

我想我更喜歡中間的最佳解決方案。

+0

好主!我們進行了三次編輯,讓它幾乎正確! –

+2

使用自定義[在std :: unique_ptr中有'SOCKET']是可能的(http://stackoverflow.com/questions/24611215/one-liner-for-raii-on-non-pointer) 'Deleter'將'SOCKET'定義爲'pointer'類型,即使它不是一個真正的指針。不知道是否可以用'std :: shared_ptr'完成同樣的工作,儘管它也支持自定義的'Deleter',但也許或者不是自定義指針?我還沒有挖掘到它看。 –

+0

我選擇了中間解決方案。 Remy表示會很好,但我現在意識到將資源編號包裝在指針容器中會造成混淆。 – Wouter