2011-01-20 113 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()将递减计数器)