c - Socket,与INADDR_ANY绑定(bind)时如何查找本地地址

标签 c sockets server ftp

我正在重新编码一个简单的 ftp 服务器,但我对 PASV 命令的实现感到困惑。

事实上,当客户端发送 PASV 命令时,我必须创建一个新的服务器套接字并将信息(地址和端口)发送回客户端,以便他可以连接到它以创建数据连接。

我一步一步做的是:

  1. 使用 INADDR_ANY 和随机端口(端口 0)创建服务器套接字
  2. 使用此套接字监听()
  3. getsockname() 这个套接字来获取它的信息
  4. 通过命令连接将信息发送回客户端
  5. 当用户需要使用数据连接时,accept() 会稍后完成

(这是正确的方法吗?)

问题是,我在服务器端创建的服务器套接字与 INADDR_ANY 绑定(bind),因此其上的 getsockname() 始终返回 0.0.0.0(因为它实际上绑定(bind)到系统外的所有 ip)。

这样的话,我应该发回什么地址给客户以及如何找到它?

真实的 ftp 服务器如何处理这个问题?

谢谢:)

最佳答案

What I do step by step is:

  1. Create a server socket with INADDR_ANY and random port (port 0)
  2. listen() with this socket
  3. getsockname() this socket to get it's infos
  4. send back the infos to the client on the command connection
  5. the accept() is done later, when the user need to use the data con

(Is that the right way to do it ?)

一般来说,是的,但是步骤 #1 和 #3 往往比这更复杂。

一方面,getsockname()在套接字实际连接到某人之前无法获取真实 IP(在这种情况下,这意味着您必须在 getsockname() 返回的套接字上调用 accept(),而不是在您调用 accept() 的套接字上) 。因此,当绑定(bind)到INADDR_ANY时,您应该只报告命令套接字连接到的接口(interface)的 IP。在这种情况下,最好将监听套接字直接绑定(bind)到该接口(interface),而不是绑定(bind)到 INAADDR_ANY完全没有。

另一件事,即使服务器计算机只安装了 1 个接口(interface),如果服务器位于 NAT 路由器后面,并且客户端位于 NAT 之外,那么您必须报告路由器的公共(public) IP,而不是服务器的监听知识产权。您必须提前知道路由器的公共(public) IP,方法是将其存储在应用程序的配置中,或者通过 uPNP 动态查询路由器本身,或者通过查询外部服务,如 http://iplookup.flashfxp.com/ 。除非路由器支持 FTP(有些是)并且足够智能,可以在通过路由器时为您替换报告的 IP,在这种情况下,您必须报告您的监听 IP。

关于c - Socket,与INADDR_ANY绑定(bind)时如何查找本地地址,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44029454/

相关文章:

php - Laravel 远程 ssh 很慢

java - Tomcat 8 IP转域名

c - 在 Linux 环境下运行的 OSX 终端上编译代码很困难

python - 通过 IPC 将二进制数据从 C 发送到 Python

java - 如何在java中建立线程套接字连接?

c - 使用 C 套接字的接口(interface)上的环回数据包

c++ - C++17 std::basic_string_view 是否会使 C 字符串的使用无效?

c - 在不关闭 MATLAB 的情况下停止 mex 函数 (C)

c - 如何在没有指数运算符的情况下用 C 编程转换多项式?

java - 当服务器被终止时,如何将变量列表转储到文件中?