2016-02-13 156 views
4

我已經在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://stackoverflow.com/a/2721734/5276801解決該問題 – RandomHash

回答

1

您需要在您的服務器中使用您的公共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

0

似乎你需要執行基本的網絡故障排除。你的描述說你可以連接到你自己網絡上的其他機器,但不能連接到另一個網絡上的機器。您可以在另一個網絡上的機器上嘗試相同類型的測試:它可以連接到自己網絡上的其他機器,可以連接到其他網絡的機器。

一些非常有價值的工具包括ping,tracepath,tcpdump和nc(netcat)。

最終,如果您可以與netcat建立連接,則可以認爲問題出在您的代碼上,但如果您無法嘗試查找網絡問題。

2

使用此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