(如何)我可以从套接字文件描述符中确定套接字系列

Asked
Viewd2594

6

我正在编写一个API,其中包含IPC函数,这些函数会将数据发送到另一个进程,该进程可能是本地进程,也可能是另一个主机。我真的希望send函数像这样简单:

 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()的效率,想知道我每次发送时是否能负担得起。

3 个答案

6

请参见 getsockname(2)。然后,您检查该家族的 struct sockaddr

编辑:作为补充,它有时对查询 info 也是有用的,在这种情况下, info libc套接字

编辑:

您真的不知道是否每次都不知道。不能简单地缓存它,因为套接字号可以通过关闭和重新打开来重新使用。我只是查看了glibc代码,似乎 getsockname 只是一个系统调用,在性能上可能很讨厌。

但是我的建议是使用某种面向对象的概念。让用户传递指向您先前返回给他的结构的指针,即让他使用您的API注册/打开套接字。然后,您可以缓存该套接字的任何内容。

2

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

  • Whenever you’re doing network communication you want to minimize data copying as much as humanly possible if you want your application to scale well.

    17 of 26February 04, 2009 22:01
  • @fizzer, tell that to Xorg guys. Yes, it matters.

    Eduard - Gabriel MunteanuFebruary 04, 2009 21:47
  • Why not? You’ll need this code anyway in the network case. Is there any evidence that the byte swap is a bottleneck in the context of IPC?

    fizzerFebruary 04, 2009 21:40
  • Because fairly often I’ll be doing local IPC and don’t want to do hton() then ntoh() on every multi-byte value.

    Chris NelsonFebruary 04, 2009 21:30
  • Though there is a point here. I’m unsure what should be done in case we assume no collaboration between endpoints: do local sockets generally expect data to be in network byte order?

    Eduard - Gabriel MunteanuFebruary 04, 2009 22:44
  • I believe that is the case, yes.

    17 of 26February 05, 2009 14:59
1

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

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

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

  • With this technique, byte swapping is only done on the receiving side. The sender never swaps - it just sets that 4 byte value before the rest of the data. By looking at the 4 bytes on the receiving end, the receiver knows whether or not they need to swap.

    17 of 26February 04, 2009 21:58
  • Right, the caveat here is that you need to be in control of both sides of the connection. Or at least be able to dictate the terms to the other side :). The original poster’s situation was unclear to me.

    17 of 26February 04, 2009 22:21
  • Yeah, though it wouldn’t work if someone decides to use this unilaterally, e.g. making a HTTP retriever.

    Eduard - Gabriel MunteanuFebruary 04, 2009 22:13
  • Unless I misunderstand you, that works for receiving but not for sending.

    Chris NelsonFebruary 04, 2009 21:20
  • The beauty of this is that as long as the sender and receiver endianness match there is no byte swapping done, even if they are not in network byte order.

    17 of 26February 04, 2009 22:02