2011-01-20 187 views
1

我正在編寫一個庫,它將通過多個路由傳輸數據; TCP,UDP,RDMA(遠程直接內存訪問),偶爾也可以通過直接函數調用將客戶機/服務器彙總爲一個二進制文件。在C++中欺騙文件描述符

我負責處理TCP,UDP,RDMA文件描述符,並一直在尋找我怎麼能實現與FunctionCallSocket類somethign相似,其將採取粗略形式:

class FunctionCallSocket 
{ 
    public: 
     FunctionCallSocket(); 
     ~FunctionCallSocket(); 

     void send(char* buf, std::size_t len); 
     void recv(char* dest, std::size_t len); 

    private: 
     char* m_outboundBuffer; 
     char* m_inboundBuffer; 
}; 

我想要做的就是像文件描述符一樣對待類,從而可以將它與TCP,UDP等文件句柄一起傳遞給select/epoll。

從我理解的文件描述符整數值是由操作系統從一個私人擁有的表生成的映射文件到ID的所以我不知何故需要欺騙這個。

關於如何實現這一點的任何想法?

回答

1

如果需要,您可以使用OS特定的調用來獲取文件描述符。例如,Unix的open函數可以做你想要的。

或者,您可以讓您的代碼讀取和寫入多態類層次結構的數據部分,這將允許您在適當的位置使用文件描述符,併爲文件I/O使用流庫(例如)。實際上,一個想法可能是編寫自定義流類來包裝TCP連接,然後使用ostream和istream作爲連接細節的包裝。

+0

有趣。調用open會保留一個唯一的文件描述符。我實際上不會通過文件描述符發送數據,而是通過函數調用FunctionCallObject擁有的指針。當數據到達inboundBuffer/outboundBuffer時,有沒有辦法改變fd,所以選擇/ epoll查看數據? – Graeme 2011-01-20 11:19:15

+0

**來自單獨的答案的評論:**使用此庫的客戶將使用他們自己的線程來展示文件句柄。他們也將從這個圖書館的獨立文件處理中進行宣傳。我想通過使用select/epoll來統一調度過程。 – Graeme 2011-01-20 11:22:42

0

如果它不是文件描述符,那麼將它傳遞給select()就沒有意義了。如果某個文件描述符存在於下面,那麼您需要一個API來公開它,或者您有一個低級別的API來將文件描述符添加到選擇集中,並使該類負責註冊它所使用的任何文件描述符。請注意,您很好地進入了異步事件處理和回調領域。

2

如果您在Linux上運行,我建議您查看eventfd - 這正是您要查找的內容。

http://www.kernel.org/doc/man-pages/online/pages/man2/eventfd.2.html

公開賽在EFD_SEMAPHORE模式FD,你可以用它來跟蹤你有

(每個write()調用將增加通過與內核存儲計數器多少排隊的事件eventfd,並且每個read()將遞減計數器)