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

Sockets 为什么在TCP中使用bind()?为什么它只在服务器端使用而不在客户端使用?,sockets,networking,tcp,network-programming,bind,Sockets,Networking,Tcp,Network Programming,Bind,我想知道bind()在TCP中的确切功能。将本地地址“绑定”到套接字是什么意思?如果它给套接字分配了一个端口号,那么我们为什么不在客户端中使用它呢?我知道端口是由操作系统在客户端自动分配的,但我并不了解所有这些是如何工作的 在bind()之后,我们监听()。绑定与listen()的关系如何?listen()会知道bind()已经执行了吗?如果是这样的话,bind()做了哪些更改以使其为人所知?我是说,成功执行返回零有什么帮助 我已经讨论了很多定义,但是没有一个地方可以详细了解所有这些。因此,如果

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

在bind()之后,我们监听()。绑定与listen()的关系如何?listen()会知道bind()已经执行了吗?如果是这样的话,bind()做了哪些更改以使其为人所知?我是说,成功执行返回零有什么帮助

我已经讨论了很多定义,但是没有一个地方可以详细了解所有这些。因此,如果有人能向我解释这一点,我将不胜感激。

它将套接字“绑定”到一个地址,否则它不知道应该侦听哪个地址(ip地址/端口对)

客户端也可以使用
bind
。例如,在一台计算机上,多个网卡连接到同一个网络,但客户端只希望被视为来自一个特定的网络地址

绑定不仅用于TCP套接字,也用于UDP套接字和其他协议。

它分配“本地”端的端口号

对于服务器套接字,这是最终的解决方法——这正是需要的:例如,将套接字绑定到web服务器的端口80

然而,对于客户端套接字,本地地址和端口通常并不重要。所以您不必
bind()
。如果服务器限制其客户端可能具有特定的端口号,或者端口号超出给定范围,那么您也可以在客户端使用
bind()

另一方面,您也可以在未调用
bind()
的套接字上
listen()
(实际上我不确定,但这是有意义的)。在这种情况下,服务器端口将是随机的,服务器进程将通过不同的方式将其端口与客户端通信。想象一下一个“双连接”协议,比如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)
bind()
定义连接的本地端口和接口地址
connect()
执行隐式
绑定(“0.0.0.0”,0)
如果以前没有执行过绑定(零被视为“任何”)

对于输出连接,这通常是可接受和首选的。操作系统将简单地绑定到“所有接口”,并选择一些高编号、未使用的端口。仅当服务器希望您来自特定端口或端口范围时,才需要在客户端上绑定。有些服务只允许从小于1024的端口号进行连接,这些端口号只能由超级用户绑定,尽管现在每个人都控制自己的机器,这并不意味着什么

对于传入连接,您必须绑定到已知端口,以便客户端知道在哪里与您联系。一旦他们这样做了,他们就给了服务器他们的本地地址/端口,这样通信就可以双向流动
listen()
仅在
bind()调用后工作


所有套接字都必须绑定,无论它们是UDP、TCP还是其他类型。我知道这是一个老问题,但我有一个新的答案:)

您可能希望连接到一个服务器,该服务器只允许每个ip有限数量的传入连接

如果您有多个网络接口卡(因此可以连接多个可能的传出IP),则可以使用bind(),在每个IP之间循环,以平衡连接,从而使连接数达到允许连接数的几倍


要获取接口和IP的列表,请参阅答案。

listen()
仅在
bind()
调用后才起作用。”否,如中所示。如果有效,则
bind()
是隐式的,并选择绑定到所有接口的半随机端口号。这通常是没有用处的(尽管很少有例外)。Brian White是正确的,
connect()
执行隐式绑定(否则,如果不先在本地保留资源,内核将不知道如何连接)。此答案不完整,因为它还负责通过ip地址监听哪些网络接口,例如
0.0.0.0