如何让Python套接字对外可见?
我之前发过一个类似的问题,但我越来越沮丧,因为我的网络设置看起来没有问题。其他软件可以从外部访问(比如 netcat 监听的服务器等),但我的脚本却不行……这是怎么回事呢?
注意:在局域网内可以正常工作,但在互联网上不行。
服务器:
import socket
host = ''
port = 80001
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host,port))
s.listen(1)
print 'Listening..'
conn, addr = s.accept()
print 'is up and running.'
print addr, 'connected.'
s.close()
print 'shut down.'
客户端:
import socket
host = '80.xxx.xxx.xxx'
port = 80001
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host,port))
s.close()
有人能帮帮我吗?
非常感谢任何帮助。
Jake
2 个回答
再次编辑补充:
我觉得你可能对套接字通信的一些基础知识还不太了解。要让套接字正常工作,你需要确保客户端和服务器上的套接字能够相互连接。根据你最新的修改,你的服务器现在绑定到了63001端口,但它是在本地回环适配器上,也就是127.0.0.1。
计算机有多个网络适配器,至少有两个:一个是本地回环适配器,它可以让你快速地在同一台机器上进行网络连接(用于测试、进程间通信等),另一个是让你连接到实际网络的网络适配器。很多计算机可能还有更多的适配器(比如虚拟适配器、无线和有线适配器等),但至少会有两个。
所以在你的服务器应用中,你需要指示它将套接字绑定到正确的网络适配器上。
host = ''
port = 63001
bind(host,port)
在Python中,这样做是将套接字绑定到回环适配器(或者说127.0.0.1/localhost)。
在你的客户端应用中,你有:
host = '80.xxx.xxx.xxx'
port = 63001
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host,port))
现在你的客户端试图连接到80.xxx.xxx.xxx(这是你的无线网络适配器)上的63001端口。
由于你的服务器在回环适配器上监听,而你的客户端在无线适配器上尝试连接,所以连接失败了,因为两者没有对上。
所以你有两个解决方案:
将客户端更改为连接到localhost,使用
host = 127.0.0.1
将服务器更改为绑定到你的互联网适配器,使用
host = 80.xxx.xxx.xxx
第一个解决方案,使用localhost,只在你的服务器和客户端在同一台机器上时有效。localhost总是指向它自己(所以叫回环),无论你尝试哪个机器。因此,如果你决定将客户端/服务器放到互联网上,你必须绑定到一个在互联网上的网络适配器。
编辑补充:
好的,根据你最新的修改,它仍然无法工作,因为 65535
是可用的最大端口。
下面的回答是针对问题的最初版本。
在你发布的代码中,你在63001端口上监听(绑定),但你的客户端应用试图连接到80端口。这就是为什么你的客户端无法与服务器通信的原因。你的客户端需要使用63001端口而不是80端口进行连接。
另外,除非你在运行HTTP服务器(或者你的Python服务器能够处理HTTP请求),否则你真的不应该绑定到80端口。
在你的客户端代码中更改:
import socket
host = '80.xxx.xxx.xxx'
port = 63001
在你的服务器代码中:
import socket
host = ''
port = 63001
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((socket.gethostbyname(socket.gethostname()), port ))
在你的服务器脚本中,你设置了 port = 80
,但是你并没有用到它。看起来服务器实际上是在63001端口上监听。而客户端则是连接到80端口。
如果你打算使用80端口,确保没有其他的HTTP服务器同时也在使用这个端口。