FTP 服务器如何处理来自同一端口的多个连接?
您好,
如果我正确掌握 FTP 协议(RFC959),在默认设置的主动模式下,服务器会建立从其端口 20 到客户端连接的 IP/端口的数据连接。
有人可以向我解释一下这实际上如何适用于多个客户端吗? (或者告诉我哪里错了)
更具体地说,我:
1)调用 socket()
2) bind()
将描述符绑定到我的 ip/端口 20
3) connect()
客户端建立数据连接
同时在处理不同客户端的另一个线程中我尝试做同样的事情 由于显而易见的原因,bind()
调用将失败。
我知道您可以使用带有 SO_REUSEADDR 的 setsockopt() 来让套接字绑定到相同的地址/端口,但是数据包是否会正确传送?我很迷失。
到目前为止,我无法找到有关此事的任何信息,因此我们将不胜感激。
Greetings,
if I grasp the FTP protocol (RFC959) correctly, in active mode with default settings, the server establishes the data connections from its port 20 to the ip/port client has connected from.
Could someone please explain to me how this actually works with multiple clients? ( or tell me where I got it wrong )
To be more specific lets say I:
1) call socket()
2) bind()
the descriptor to my ip/port 20
3) connect()
the client to establish the data connection
meanwhile in another thread handling a different client i attempt to do the same
the bind()
call will fail for obvious reasons.
I am aware that you can use setsockopt() with SO_REUSEADDR to let sockets bind to the same address/port, but are packets going to be delivered properly? I am quite lost.
I wasn't able to find anything on this matter so far, so any help would be greatly appreciated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
套接字连接使用 4 个参数进行识别 - 源 IP、源端口、dest.IP 和 dest.port。如果是活动连接,则每个连接的第四个参数(目标端口,客户端计算机上的端口)将有所不同。当涉及路由器/NAT 时就会变得复杂,并且在许多情况下主动模式不起作用。
Socket connection is identified using 4 parameters - source IP, source port, dest.IP and dest.port. In case of active connection 4th parameter (destination port, the one on the client computer) will be different for each connection. Complexities come when routers/NAT are involved, and then in many cases Active mode doesn't work.
客户端通常不绑定。调用
socket
,然后调用connect
。将为该连接分配一个唯一的本地端口。在服务器上,
socket
、bind
和listen
设置服务器端口。accept
返回唯一的客户端连接。Clients don't normally bind. call
socket
thenconnect
. A unique local port will be assigned to the connection.On the server,
socket
,bind
andlisten
set up the server port.accept
returns the unique client connection.FWIW,
SO_REUSEADDR
的目的不是让服务器在单个 TCP 端口上获得多个连接……而是让 TCP 服务器可以在连接处于活动状态时快速重新启动;否则它必须等待内核连接表超时。有趣的是,UDP 套接字可以声明
SO_REUSEADDR
以允许单播和多播应用程序侦听同一UDP端口。FWIW, the purpose of
SO_REUSEADDR
is not for a server to get multiple connections on a single TCP port... it is so a TCP server can restart itself quickly while connections are active; otherwise it would have to wait for them to timeout of the kernel's connection table.Interestingly, UDP sockets can assert
SO_REUSEADDR
to allow unicast and multicast applications to listen on the same UDP port.正如您所注意到的,只要您在两个套接字上设置了 SO_REUSEADDR 套接字选项,并且它们都没有监听,那么 bind() 就不会失败 - 它们两者可以绑定到同一个本地地址。
数据包被正确传送,因为一个套接字连接到一个对等地址,而另一个套接字连接到另一个地址。也就是说,当数据包到达时,源地址和端口以及目标地址和端口用于确定将其发送到哪个本地套接字(如果有)。
As you've noted, as long as you set the
SO_REUSEADDR
socket option on both sockets, and neither of them is listening, then thebind()
will not fail - they can both be bound to the same local address.Packets are delivered correctly, because one socket is connected to one peer address, and the other socket is connected to another. That is, when a packet arrives the source address and port as well as the destination address amd port is used to determine which local socket to send it to (if any).