2014-06-16 50 views
-2

Server代碼:我的IP和端口號碼應該是多少?是這樣,errno 10061不會出現?

import socket 
import base64 

filename = open("received.xvid","ab") 

TCP_IP = '127.0.0.1' 
TCP_PORT = 5005 
BUFFER_SIZE = 1024 

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
s.bind((TCP_IP, TCP_PORT)) 
s.listen(1) 

conn, addr = s.accept() 
data = conn.recv(16) 
filesize = int(data) 
iter = filesize//BUFFER_SIZE 
i = 0 

while (i < iter): 
    data = conn.recv(BUFFER_SIZE) 
    filename.write(data.decode('base64')) 
    if not data: 
     continue 
    i = i + 1 

data = conn.recv((filesize - (iter*BUFFER_SIZE))) 
filename.write(data.decode('base64')) 
filename.close() 

conn.close() 

客戶端代碼:

import socket 
import time 
import base64 

TCP_IP = '127.0.0.1' 
TCP_PORT = 5005 
BUFFER_SIZE = 1024 

filename = open("test.xvid","rb") 
MESSAGE = base64.b64encode(filename.read()) 
filesize = '%16s'%len(MESSAGE) 

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
s.connect((TCP_IP, TCP_PORT)) 
s.send(filesize) 
time.sleep(1) 
s.send(MESSAGE) 
s.close() 

當我運行客戶端代碼,我得到「socket.error:[錯誤10061]無連接可以作出,因爲目標機器積極拒絕「。我不明白爲什麼。我應該用什麼代替TCP_IP和TCP_PORT來使代碼有效?

這是我輸入命令netstat -tnl時得到的結果。

顯示協議統計信息和當前TCP/IP網絡連接。

NETSTAT [-a] [-b] [-e] [-f] [-n] [-o] [-p] [-r] [-s] [-x] [-t] [interval]

-a顯示所有連接和偵聽端口。 -b顯示創建每個連接或 偵聽端口時涉及的可執行文件。在某些情況下,衆所周知的可執行文件主機會顯示多個獨立組件,並且在這些情況下,會顯示創建連接 或監聽端口所涉及的組件序列。在這種情況下,可執行文件 名稱位於底部的[]中,最上面的是它調用的組件, 等等,直到達到TCP/IP。請注意,此選項 可能非常耗時,並且會失敗,除非您有足夠的 權限。 -e顯示以太網統計信息。這可能與-s 選項結合使用。 -f顯示外部 地址的完全限定域名(FQDN)。 -n以數字形式顯示地址和端口號。 -o顯示與每個連接關聯的擁有進程ID。 -p proto顯示由proto指定的協議的連接;原型 可能是以下任何一種:TCP,UDP,TCPv6或UDPv6。如果與-s 選項一起使用來顯示每個協議的統計信息,則proto可以是以下任何一種:IP,IPv6,ICMP,ICMPv6,TCP,TCPv6,UDP或UDPv6。 -r顯示路由表。 -s顯示每個協議的統計信息。默認情況下,IP,IPv6,ICMP,ICMPv6,TCP,TCPv6,UDP和UDPv6的統計數據爲 ; -p選項可用於指定默認的子集。 -t顯示當前的連接卸載狀態。 -x顯示NetworkDirect連接,偵聽器和共享的 端點。 -y顯示所有連接的TCP連接模板。 不能與其他選項結合使用。 時間間隔重新顯示所選統計數據,每次顯示之間暫停間隔秒數 。按CTRL + C停止重新顯示 統計信息。如果省略,netstat將打印當前的配置信息 一次。

+0

您是否在同一臺計算機上運行客戶端和服務器? –

+0

你確定服務器進程正在運行嗎?啓動服務器,然後在shell窗口中輸入命令'netstat -tnl'併發布結果UNEDITED。 – zwol

+0

當我在同一臺機器上運行服務器和客戶端時,情況很好。當我在不同的機器上運行它們時,即出現問題時。 – Iguana

回答

0

When I run the server and client on the same machine, things are fine. When I run them on different machines, that is when the problems arise.

OK,我知道你的問題是什麼。

TCP_IP = '127.0.0.1' 

您已將此IP地址硬編碼到服務器和客戶端。這是一個特殊的IP地址,意思是這臺機器,只有這臺機器。當您在bind()中使用它時,服務器將偵聽來自同一臺計算機的連接而只有。當您在connect()中使用它時,客戶端會嘗試連接到運行在同一臺計算機上的服務器。

偵聽來自任何機連接,這可能正是你的服務器的意圖,你叫bind與特殊IP地址0.0.0.0。 (A 完整服務器用於生產用途需要做一些稍微比這更復雜,但是這是不夠的這樣一個測試程序。)

爲了有一個客戶端連接到服務器的另一臺機器上運行,它需要將另一臺機器的DNS名稱作爲命令行參數,並通過getaddrinfo運行該命令以獲取要連接的IP地址。

您應該購買並閱讀UNIX Network Programming, Volume 1, 3rd EditionAdvanced Programming in the UNIX Environment。它們很貴,但它們是值得的。他們會充實上述建議,並教你許多其他你需要知道的事情,如果你要編寫一個完整的網絡服務器或客戶端。(請確保獲得第三版UNIX網絡編程;早期版本包含一堆不需要知道的廢棄垃圾。第二卷UNIX網絡編程也是有價值的,但不適用於您的高級編程...也不太直接相關,尤其是在Windows環境下,因爲我懷疑你是來自錯誤消息的措辭。)

2
  • 如果發生這種情況總是,這意味着機器存在,但它 沒有服務監聽指定的端口上,或者是有 防火牆阻止你。
  • 如果偶爾發生並且重試成功,則可能是 ,因爲服務器有完整的「積壓」。

當您在監聽套接字上等待accept時,您將被置於積壓狀態。這個積壓是有限的,並且非常短 - 值1,2或3並不少見 - 所以操作系統可能無法排隊請求accept消耗。

積壓是listen函數的一個參數 - 所有語言和平臺在這方面基本上具有相同的API。如果您控制服務器並且可能從某些設置文件或註冊表中讀取此參數,則該參數通常是可配置的。調查如何配置您的服務器。

無論你是否可以增加服務器積壓,你確實需要重試邏輯在客戶端代碼這個問題來應對,因爲即使有長期積壓的服務器可能在收到很多其他的請求當時的那個港口。

如果NAT路由器將映射的端口用盡,那麼NAT路由器會出現此錯誤的可能性很小。我認爲我們可以放棄這種可能性,因爲路由器在耗盡之前同時連接到相同的目的地址/端口。

而且點擊此處瞭解原因:

相關問題