我家里有一台安装了 NGINX 的 Debian 服务器。目前它只提供与 nginx 一起安装的默认 index.html。我给自己取了一个主机名迪努并获得 TLS 证书让我们加密
我可以使用我的主机名在 Web 浏览器上完美访问我的默认 nginx 网站,并且一切运行正常。
但是我需要在这个 Debian 服务器上用 C 实现一个简单的服务器套接字,监听端口 8080,并通过互联网从任何一台计算机用 C 语言编写的客户端套接字连接到它。
我的问题是,尽管已经在我的家庭路由器中转发了端口 8080,并且已将端口 8888 添加到 Debian 服务器防火墙(sudo ufw allow 8888/tcp
和sudo ufw allow 8888/udp
),但我仍然无法连接到服务器套接字。
如果我在同一台机器上运行服务器和客户端套接字程序,它们在连接客户端时工作正常,localhost
所以我知道代码工作正常。问题是,当我在 Debian 服务器中运行服务器套接字程序并在笔记本电脑中运行客户端套接字程序时,无论我使用 Debian 本地地址还是 dynu 主机名,它们都无法连接。
当我运行客户端时,它以错误结束Connection refused
,并且服务器套接字程序甚至没有闪烁,它只是停留在等待端口 8888 上的连接。
我在开头提到了 nginx、主机名和证书,因为我不知道这是否会与独立于 nginx 的 c 服务器套接字发生冲突,我的意思是,我不知道这是否是 nginx 的限制。我不认为这是因为我使用的端口与 nginx 配置的端口不同,但我不确定。我甚至对 nginxsudo systemctl stop nginx
服务器进行了 'ed 操作,但这没有帮助。
我错过了什么?
更新:好的,我运行了我的服务器套接字并让它监听,然后我运行netstat -ntlp
,现在我可以看到我的服务器套接字应用程序:
tcp 0 0 127.0.0.1:8888 0.0.0.0:* LISTEN 8959/socket-server/
我不得不改为端口 8888,因为端口 8080 正在被“WWW Cache”(不管它是什么)使用,但客户端仍然无法连接。
我的套接字服务器绑定到通过以下方式获取的地址getaddrinfo(NULL, port, &hints, &server_info)
答案1
您的 netstat 输出解释了正在发生的事情:
$ netstat -ntlp |复制代码 TCP 0 0127.0.0.1:8888 0.0.0.0:* 侦听 8959/套接字服务器/
127.0.0.1 地址是“localhost”地址,此行表示您的服务器仅在“localhost”上监听!
您应该重新配置或修补您的服务器,以便它监听可以在其运行的机器之外访问的地址。通常为 0.0.0.0(这意味着它可以通过连接到本地机器的“任何”地址访问。)
如果您有它的 C 代码,请查看它是否将其套接字绑定到INADDR_LOOPBACK
,这意味着 127.0.0.1 地址,换句话说就是“localhost”。您可以尝试将其更改为INADDR_ANY
,这意味着 0.0.0.0 地址,该地址将可通过网络访问(假设连接未被防火墙或其他类型的过滤阻止)。
更新:的手册页获取地址信息(3)解释传递的节点地址为 NULL 时的行为:
如果
AI_PASSIVE
在 中指定了该标志hints.ai_flags
,并且node
为NULL
,则返回的套接字地址将适合绑定将接受连接的套接字。返回的套接字地址将包含“通配符地址”(INADDR_ANY
对于 IPv4 地址)。通配符地址由打算接受任何主机网络地址上的连接的应用程序(通常是服务器)使用。如果node
不是NULL
,则AI_PASSIVE
忽略该标志。如果
AI_PASSIVE
中未设置标志hints.ai_flags
,则返回的套接字地址将适合用于 connect(2)、sendto(2) 或 sendmsg(2)。如果node
是NULL
,则网络地址将设置为环回接口地址(INADDR_LOOPBACK
对于 IPv4 地址);这由打算与在同一主机上运行的对等方进行通信的应用程序使用。
解决问题的一种可能方法是将“0.0.0.0”地址传递给函数:
getaddrinfo("0.0.0.0", port, &hints, &server_info)
另一个可能的解决方案是更新hints.ai_flags
以包括AI_PASSIVE
。
答案2
如果它在本地机器上运行良好,localhost
那么很可能是 Debian 服务器上的防火墙问题。ufw
你使用的那些命令看起来应该已经奏效,但也许可以尝试sudo ufw allow 8080
不使用 来指定协议/
。您可以随时使用 检查防火墙的开放端口,以iptables -L
查看命令是否设置正确。
以下是更多数据ufw
如果您想尝试不同的语法。如果您想要更直接的方法,您可以直接使用 来设置防火墙设置iptables
,使用以下命令:
$ sudo iptables -A INPUT -p tcp --dport 8080 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
$ sudo iptables -A OUTPUT -p tcp --sport 8080 -m conntrack --ctstate ESTABLISHED -j ACCEPT
希望这可以帮助。