通过互联网在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,但是我找不到任何相关的东西。

+0

也许防火墙? –

+0

我试过在Windows上关闭防火墙。我们有办法在Fedora上关闭它吗? –

+0

防火墙或NAT?尽管Portforwarding应该修复NAT。可能是超时错误,请参阅http://*.com/a/2721734/5276801解决该问题 – RandomHash

您需要在您的服务器中使用您的公共IP地址或0.0.0.0,并确保您的调制解调器/路由器允许在指定端口(通常称为端口转发)的传入连接。

希望它有帮助!

+0

我需要在服务器代码中添加公共IP地址吗? client.py中的IP地址只是公共的。 –

+0

@SanyamJain是的。使用'192.168.0.104'只会监听局域网连接。使用你的公共IP地址或'0.0.0.0'。 – cdonts

+0

服务器应该使用'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() 
+0

默认情况下,5001外部不会进入5001内部?但是如果你映射端口,你可以让其他端口去其他内部端口? – Luke

+0

@Luke正确。默认情况下,您的外部端口不映射到内部端口。您可以将任何外部端口映射到任何内部端口映射;请务必避免低于1000的端口。 – TisteAndii

+0

确实,这些端口已被某些服务使用。我还发现了一些盗用9000端口的东西,我认为这很奇怪。 – Luke