通过互联网在Python中的套接字连接?
我已经在Python 2.7.x中创建了一个基本的客户端服务器套接字程序,即使在不同的机器上,它在同一个网络上也运行得很好,但是当我在不同的网络上运行服务器和客户端时(服务器在朋友的网络上, )它不会返回任何错误并继续等待。我只是不明白如何调试代码。我通过端口80上的所有服务来使用端口80.我还在两台机器上的端口80上完成了端口转发。通过互联网在Python中的套接字连接?
我的代码如下:
client.py
import socket
s = socket.socket()
host = '103.47.59.130'
port = 80
s.connect((host, port))
while True:
print "From Server: ", s.recv(1024) #This gets printed after sometime
s.send(raw_input("Client please type: "))
s.close()
server.py
import socket
s = socket.socket() # Create a socket object
host = '192.168.0.104' #private ip address of machine running fedora
port = 80
s.bind((host, port))
s.listen(5)
c, addr = s.accept()
print 'Got connection from', addr #this line never gets printed
while True:
c.send(raw_input("Server please type: "))
print "From Client: ", c.recv(1024)
c.close()
有时候输出**从服务器**,但不列入来回发送任何消息。
PS:我已经搜索了Stack Overflow,但是我找不到任何相关的东西。
您需要在您的服务器中使用您的公共IP地址或0.0.0.0
,并确保您的调制解调器/路由器允许在指定端口(通常称为端口转发)的传入连接。
希望它有帮助!
我需要在服务器代码中添加公共IP地址吗? client.py中的IP地址只是公共的。 –
@SanyamJain是的。使用'192.168.0.104'只会监听局域网连接。使用你的公共IP地址或'0.0.0.0'。 – cdonts
服务器应该使用'0.0.0.0',以便代码可以在很多机器上运行,但如果'192.168.0.104'实际上是服务器机器的地址,它仍然可以工作。服务器位于NAT后面,正如这里指出的那样,您需要在NAT上配置端口转发以将端口80发送到'192.168.0.104'。您的朋友的ISP可能会阻止传入的连接请求,或者可能只有80个,所以请试用其他人。 – tdelaney
似乎你需要执行基本的网络故障排除。你的描述说你可以连接到你自己网络上的其他机器,但不能连接到另一个网络上的机器。您可以在另一个网络上的机器上尝试相同类型的测试:它可以连接到自己网络上的其他机器,可以连接到其他网络的机器。
一些非常有价值的工具包括ping,tracepath,tcpdump和nc(netcat)。
最终,如果您可以与netcat建立连接,则可以认为问题出在您的代码上,但如果您无法尝试查找网络问题。
使用此software来实现端口转发。我建议你使用其他端口为您的服务器,比如说5006,以避免与使用一个很常用的端口像80基本上任何问题,软件的工作原理是这样的:
- 您单击连接,它搜索路由器,如果它找到你的,它列出现有的端口映射。
- 您创建了一个端口映射(右),默认的协议是TCP
- 您的路由器选择一个端口,比如5001(称为外部端口)
- 您的服务器上选择一个端口,也许5006 (称为内部端口)
- 然后将指示路由器使用您的私有IP,特别是端口5006,将所有到达端口5001的数据转发到您的服务器。
因此,您所有的客户端必须将数据发送到您的服务器的公共IP,特别是端口5001。这些数据当然会首先到达您的路由器,它将按照配置运行,并将所有内容转发到您的服务器的端口5006.所有这些仅在您的Internet网关支持端口转发时才有效。
客户:
import socket
s = socket.socket()
host = '103.47.59.130'
port = 5001
s.connect((host, port))
while True:
try:
print "From Server: ", s.recv(1024)
s.send(raw_input("Client please type: "))
except:
break
s.close()
服务器:
import socket
s = socket.socket() # Create a socket object
host = '192.168.0.104' #private ip address of machine running fedora
port = 5006
s.bind((host, port))
s.listen(5)
c, addr = s.accept()
print 'Got connection from', addr
while True:
c.send(raw_input("Server please type: "))
print "From Client: ", c.recv(1024)
c.close()
默认情况下,5001外部不会进入5001内部?但是如果你映射端口,你可以让其他端口去其他内部端口? – Luke
@Luke正确。默认情况下,您的外部端口不映射到内部端口。您可以将任何外部端口映射到任何内部端口映射;请务必避免低于1000的端口。 – TisteAndii
确实,这些端口已被某些服务使用。我还发现了一些盗用9000端口的东西,我认为这很奇怪。 – Luke
也许防火墙? –
我试过在Windows上关闭防火墙。我们有办法在Fedora上关闭它吗? –
防火墙或NAT?尽管Portforwarding应该修复NAT。可能是超时错误,请参阅http://stackoverflow.com/a/2721734/5276801解决该问题 – RandomHash