如何确定打开的套接字是 TCP 还是 unix 域套接字?

Posted

技术标签:

【中文标题】如何确定打开的套接字是 TCP 还是 unix 域套接字?【英文标题】:How do I determine whether open socket is TCP or unix domain socket? 【发布时间】:2014-07-09 10:20:30 【问题描述】:

我的代码通过了一个打开的套接字。此套接字可以是 TCP 套接字 (AF_INET) 或 Unix 域套接字 (AF_UNIX)。

根据套接字的域,需要进行不同的处理。特别是如果套接字绑定到一个地址,那么我可能想以不同的方式 accept 传入连接。

确定我通过的套接字是unix域套接字还是TCP套接字的最佳方法是什么?该解决方案至少需要在 OS X 和 Linux 上运行。

getsockopt 似乎允许获取套接字的类型(例如 SOCK_STREAM 等),但不允许获取域。

getsockname 将为 OSX 上的 unix 域套接字返回零长度,但这正式是 bug,Linux 行为是 different。

【问题讨论】:

【参考方案1】:

getsockname 返回的struct sockaddr 的第一个成员是sa_family,只需针对符号常量进行测试即可。 OSX 上的 bug 允许您在返回的地址结构为零字节时假设 unix 域,对于其他平台和域,只需检查返回的结构。

【讨论】:

【参考方案2】:

getsockname() 是唯一一个跨平台套接字 API 来查询套接字的本地绑定地址,以及它的地址族。

至少在 Windows 上,您可以使用 getsockopt(SOL_SOCKET, SO_PROTOCOL_INFO) 检索具有 iAddressFamily 字段的 WSAPROTOCOL_INFO 结构。也许在其他操作系统上有类似的特定于平台的 API。

【讨论】:

以上是关于如何确定打开的套接字是 TCP 还是 unix 域套接字?的主要内容,如果未能解决你的问题,请参考以下文章

TCP 环回连接与 Unix 域套接字性能

UNIX域套接字

UNIX域协议(命名套接字)

《Unix 网络编程》15:Unix 域协议

我如何获得在 unix 域套接字中排队的数据报数量

可以在Unix域套接字上使用SO_REUSEPORT吗?