为什么在TCP中使用bind()?为什么它仅用于服务器端而不是客户端?

Cro*_*ode 46 sockets networking network-programming tcp bind

我想知道TCP中bind()的确切功能.将本地地址"绑定"到套接字是什么意思?如果它正在为套接字分配端口号,那么为什么我们不在客户端中使用它?我知道端口是由操作系统在客户端自动分配的,但我并没有全面了解所有这些是如何工作的.

在bind()之后,我们监听().绑定是如何与listen()相关的?listen()是否知道bind()已被执行?如果是这样,bind()会做出哪些更改以便知道它?我的意思是,为成功执行返回零如何帮助?

我已经经历了很多定义,但没有在哪里可以详细了解所有这些.所以,如果有人能够向我解释这一点,我将不胜感激.

glg*_*lgl 21

它分配"本地"端的端口号.

对于服务器套接字,这是最终的方法 - 它正是所需要的:例如,将您的套接字绑定到Web服务器的端口80.

但是,对于客户端套接字,本地地址和端口通常不重要.所以你没有bind().如果服务器将其客户端限制为可能具有某个端口号或给定范围之外的端口号,则也可以bind()在客户端使用.

另一方面,你可能也可以listen()在你没有调用的套接字上bind()(实际上我不确定,但它会有意义).在这种情况下,您的服务器端口将是随机的,服务器进程将通过不同的方式将其端口传递给客户端.想象一下"双连接"协议,例如FTP,您可以在其中拥有控制连接和数据连接.数据连接侦听的端口完全是任意的,但必须传送到另一端.因此使用并传达"自动确定的端口".

Python中的一个例子:

import socket
s = socket.socket() # create your socket
s.listen(10) # call listen without bind
s.getsockname() Which random port number did we get?
# here results in ('0.0.0.0', 61372)

s2 = socket.socket() # create client socket
s2.connect(('localhost', 61372)) # connect to the one above
s3, x = s.accept() # Python specific use; s3 is our connected socket on the server side
s2.getpeername()
# gives ('127.0.0.1', 61372)
s2.getsockname()
# gives ('127.0.0.1', 54663)
s3.getsockname()
# gives ('127.0.0.1', 61372), the same as s2.getpeername(), for symmetry
s3.getpeername()
#gives ('127.0.0.1', 54663), the same as s2.getsockname(), for symmetry
#test the connection
s2.send('hello')
print s3.recv(10)
Run Code Online (Sandbox Code Playgroud)

  • 这个答案是不完整的,因为它还负责通过 IP 地址侦听哪些网络接口,例如“0.0.0.0” (2认同)

Som*_*ude 10

它将套接字"绑定"到一个地址,否则它不知道它应该监听哪个地址(IP地址/端口对).

并且bind也可以在客户端使用.一个示例是在具有连接到同一网络的多个网卡的计算机上,但是客户端仅希望被视为来自一个特定网络地址.

绑定不仅用于TCP套接字,也用于UDP套接字,以及其他协议.


Bri*_*ite 10

bind()定义连接的本地端口和接口地址. 如果之前没有完成connect()一个隐含的bind("0.0.0.0", 0)做法(零被视为"任何").

对于传出连接,这通常是可接受的并且是优选的.操作系统将简单地绑定到"所有接口"并选择一些高编号的未使用端口.如果服务器希望您来自特定端口或端口范围,则只需要在客户端上绑定.有些服务只允许端口号小于1024的连接,只能由超级用户绑定,但现在每个人都控制自己的机器并不意味着什么.

对于传入连接,您必须绑定到已知端口,以便客户端知道与您联系的位置.一旦他们这样做,他们就给服务器提供了本地地址/端口,以便通信可以向两个方向流动. listen()只会在bind()通话后工作.

所有套接字都必须绑定,无论它们是UDP,TCP还是其他.它并不总是明确地完成.

  • 如果它有效,那么“bind()”是隐式的,并选择绑定到所有接口的半随机端口号。这通常没有用(尽管也有极少数例外)。 (3认同)
  • “`listen()` 仅在调用 `bind()` 后才起作用。” 不,正如您在[我的示例](http://stackoverflow.com/a/12763313/296974)中看到的那样。 (2认同)