Linux套接字文件描述符通常适用于散列

问题描述:

我正在编程一个Linux多用户服务器,并且每个接受的连接返回一个包含该连接的套接字文件描述符的int。我还有一个对应于每个连接的对象UserConnection。我使用散列表(C++ STL unordered_map<int, UserConnection>)来存储套接字文件描述符(键)和对象(值)的键值对。Linux套接字文件描述符通常适用于散列

把套接字文件描述符作为关键字放在散列表中是否安全? Linux的套接字号分配有没有任何模式可能不适用于散列函数?

+1

假设您在套接字关闭时移除了键(理想情况下,就在之前,为了避免竞争条件,如果关闭套接字并且另一个线程使用相同的fd打开套接字),我没有看到任何明显的问题。 – ShadowRanger

+0

良好的电话:谢谢!我更改了UserConnection,并将套接字移到了析构函数中,这样只有在ConnectionManager类的关键字上调用unordered_map :: erase时才能完成。 – Anton

+1

您也可以预先将用于描述符的整数值表格构建为散列。没有必要在飞行中对所有这些进行哈希。它也好像一个简单的稀疏矢量也能很好地工作。一个更有趣的应用可能是......一个独特的连接是4元组{源IP,源端口,目的IP,目的端口}。使用散列表并消化4元组可能更适合参与。最后,您可能需要键入哈希以避免潜在的DoS。我相信[内核切换到SipHash](https://lwn.net/Articles/711167/)这样的应用程序。 – jww

manual page for open(2)显式地规定,最低未使用的文件描述符被分配到新的文件描述符:

成功调用返回的文件描述符将成为 编号最低的文件描述符目前没有开放的处理。

似乎从socket(2)错过了类似的措词,但我认为这是一个相当安全的假设 - 这同样适用于套接字。

然后,创建套接字将导致单调增加文件描述符,为新的套接字,这将在第一次机会将被重用。因此,这是哈希的理想用例。