【问题标题】:Is it always required to bind a socket?是否总是需要绑定套接字?
【发布时间】:2011-12-26 14:41:41
【问题描述】:

嗯,我的问题可能看起来像一个基本的东西,但我是网络编程方面的新手。 我想知道:

1) 是否总是需要绑定套接字才能从中接收消息?我看到一个嗅探器代码(原始套接字),其中一个直接调用recvfrom,另一段代码调用bind,然后是接收。

2) AF_* 和 PF_* 系列有什么区别?后者与POSIX有关吗? 哪个是推荐的?

【问题讨论】:

  • 1) 不,UDP 接收的绑定是可选的。
  • stackoverflow.com/questions/2549461/…。 IIRC,P 代表协议(家族),而 A 代表地址。
  • @Kerrek SB:但是我所指的嗅探器代码也捕获了来自其他协议的数据包,但它仍然没有被调用bind
  • @Aif:协议族没问题,但地址类型是什么?
  • @kingsmasher1:AF_INET、AF_INET6、AF_UNIX 等等...man socket 了解详情。

标签: c linux sockets


【解决方案1】:

不,你不需要 bind()。

如果您正在使用 TCP 或 UDP 套接字,您计划使用 connect() 或使用 sendto() 将数据包发送到目的地,当您尝试使用时,内核会自动将套接字绑定到合适的端口号连接或发送。这通常是首选方式。 bind()ing 客户端套接字被认为是有害的。

AF_UNIX 套接字也是如此——客户端不需要绑定,正常情况下也不应该这样做。

【讨论】:

  • 所以你不同意KerrekSB,他说它只用于接收数据包。对?从上面的链接中可以看出,甚至不需要连接。只需致电socket,然后拨打recvfrom
  • 我说的是 TCP 或 UDP 套接字。原始套接字中发生的事情并不真正相关。
  • 你能解释一下为什么绑定客户端套接字被认为是有害的吗?
  • 绑定客户端套接字是有害的,因为 1) 您可以选择一个正在使用的本地端口号,以及 2) 您的应用程序可能与 NAT 不兼容,后者会更改目标的明显源端口号。
  • ICMP 数据包呢?在使用 sendto() 和 recvfrom() 之前是否需要绑定?
【解决方案2】:

我不了解 Linux,但在 Windows 上,如果在未绑定的套接字上调用 recvfrom(),它将失败并出现 WSAEINVAL 错误。

【讨论】:

  • 我认为尝试在未绑定到特定端口的 UDP 套接字上接收数据包没有用处,除非您已经发送了一些。可以将套接字绑定到“无关”端口,然后使用getsockname 找到该端口。例如,如果我想使用 UDP 从服务器接收数据包,但使用 TCP 发送命令(同时) - 例如,在某些流式传输情况下,我只在 UDP 中接收,从不发送。我必须绑定到端口 0(不在乎),然后通过我的协议 (TCP) 将端口号传递给服务器。
【解决方案3】:

对于只发送数据的客户端,不需要绑定。

对于向服务器发送请求,然后接收响应的客户端,不需要绑定。服务器可以使用传入数据的IP地址和端口号。

对于只接收数据或在将数据发送回服务器之前接收数据的客户端,绑定是必要的。服务器如何知道将数据发送到哪里?从这个意义上说,“客户端”就像一个“服务器”,需要一个位置(绑定端口)来接收数据。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-04-30
    • 1970-01-01
    • 2013-03-08
    • 2013-06-03
    • 1970-01-01
    • 2018-02-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多