【问题标题】:(How) Can I determine the socket family from the socket file descriptor(如何)我可以从套接字文件描述符中确定套接字系列吗
【发布时间】:2010-10-05 12:37:08
【问题描述】:

我正在编写一个 API,其中包含 IPC 函数,这些函数将数据发送到另一个可能是本地或另一个主机上的进程。我真的很希望发送功能如此简单:

int mySendFunc(myDataThing_t* thing, int sd);

调用者不必知道——在 mySendFunc() 调用的直接上下文中—— sd 是指向本地进程还是远程进程。在我看来,如果我可以这样的话:

switch (socketFamily(sd)) {
case AF_UNIX:
case AF_LOCAL:
   // Send without byteswapping
   break;
default:
   // Use htons() and htonl() on multi-byte values
   break;
}

有人建议我可以将 socketFamily() 实现为:

unsigned short socketFamily(int sd)
{
   struct sockaddr sa;
   size_t len;
   getsockname(sd, &sa, &len);   
   return sa.sa_family;
}

但我有点担心 getsockname() 的效率,想知道我是否可以负担得起每次发送。

【问题讨论】:

  • 我注意到你的最后一个问题,我已经编辑了我的帖子。

标签: c sockets ipc


【解决方案1】:

getsockname(2)。然后,您检查 struct sockaddr 的家庭。

编辑:作为旁注,查询 info 有时也很有用,在这种情况下 info libc sockets

编辑:

你真的不能不每次都查一下就知道了。它不能简单地被缓存,因为套接字号可以通过关闭和重新打开来重用。我刚刚查看了 glibc 代码,似乎 getsockname 只是一个系统调用,这在性能方面可能很糟糕。

但我的建议是使用某种面向对象的概念。让用户将指针传递给您之前返回给他的结构,即让他使用您的 API 注册/打开套接字。然后你可以缓存任何你想要的关于那个套接字的东西。

【讨论】:

  • 我很困惑,但后来我意识到你可以传入的每一个不同的结构都有第一个元素作为家庭的无符号短。 my_sockaddr.sa_family == AF_UNIX
【解决方案2】:

为什么不总是按网络字节顺序发送?

【讨论】:

  • 因为我经常会做本地 IPC,不想在每个多字节值上做 hton*() 然后 ntoh*()。
  • 为什么不呢?无论如何,在网络案例中您都需要此代码。是否有任何证据表明字节交换是 IPC 上下文中的瓶颈?
  • @fizzer,告诉 Xorg 家伙。是的,这很重要。
  • 当您进行网络通信时,如果您希望应用程序能够很好地扩展,您希望尽可能减少人为的数据复制。
  • 虽然这里有一点。如果我们假设端点之间没有协作,我不确定应该怎么做:本地套接字通常期望数据按网络字节顺序排列吗?
【解决方案3】:

如果您控制客户端和服务器代码,我有一个不同的建议,我过去曾成功使用过。

让消息的前四个字节为已知整数值。然后接收器可以检查前四个字节以查看它是否与已知值匹配。如果匹配,则不需要进行字节交换。

当两台机器具有相同的字节序时,这使您不必进行字节交换。

【讨论】:

  • 除非我误解了你,否则它适用于接收但不适用于发送。
  • 使用这种技术,字节交换只在接收端进行。发送者从不交换——它只是在其余数据之前设置那个 4 字节值。接收端通过查看接收端的 4 个字节,就知道是否需要交换。
  • 这样做的好处在于,只要发送方和接收方字节序匹配,就不会进行字节交换,即使它们不是网络字节顺序。
  • 是的,但如果有人决定单方面使用它,它就行不通了,例如制作一个 HTTP 检索器。
  • 对,这里需要注意的是您需要控制连接的两端。或者至少能够向对方口述条款:)。我不清楚原始发帖人的情况。
猜你喜欢
  • 2010-11-17
  • 1970-01-01
  • 2012-11-02
  • 1970-01-01
  • 1970-01-01
  • 2011-03-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多