2013-02-18 300 views
1

我正在寫一個TCP客戶端/服務器,我一直在代碼的後半部分打這個損壞的PIP錯誤。由於對Python和套接字編程的理解有限,我一直無法找到原因,因此我無法解決問題。我將不得不包含所有的代碼,因爲可能會有某種衝突導致我不知道的問題,對於長篇文章感到抱歉。Python 3:TCP客戶端/服務器斷開管道錯誤

我已經標記了我遇到下面的問題,到此爲止的所有內容都運行良好。

服務器代碼:

import os 
from socket import * 
import urllib 
import time 

HOST = '' #We are the host 
PORT = 29876 
PORT2 = 29877 
ADDR = (HOST, PORT) 
ADDR2 = (HOST, PORT2) 

BUFFSIZE = 4096 


serv = socket(AF_INET,SOCK_STREAM) 
serv.bind(ADDR,) 
serv.listen(5) 
print ('listening... \n') 


conn,addr = serv.accept() 
print (conn,addr) 
print ('...connected \n') 

with open(os.path.expanduser("~/.ssh/id_rsa.pub")) as f: 
    key = f.read() 
    conn.sendall(key) 
print("Key Sent... \n") 


data = conn.recv(BUFFSIZE) 
with open('ip.txt', 'w') as myfile: 
    myfile.write(str(data)) 

with open("ip.txt", "r") as myfile: 
    ip=myfile.read().replace('\n','') 
print("The client IP is: " + ip + "\n") 

conn.close() 


ver = socket(AF_INET,SOCK_STREAM) 
ver.bind(ADDR2,) 
ver.listen(5) 
print('listening...\n') 

build,addr = ver.accept() 
print (build,addr) 
print('...connected\n') 

#Get Version 
version = urllib.urlopen("http://p.b.r.com/pa/b/latest.txt") 
print(version.read()) 

#IT IS SENDING THIS LAST PIECE OF DATA THAT CAUSES THE BROKEN PIPE ERROR 
version = str(version.read()) 
ver.send(version) 

客戶端代碼:

from socket import * 
from winreg import * 
import os 
import socket 
import platform 
import string 
import time 

#Detect OS 
os = platform.system() 
print("Your system is running "+ os) 

#Set Host address and port 
HOST = 'xxx.xxx.xxx.xxx' 
PORT = 29876 
PORT2 = 29877 
ADDR = (HOST,PORT) 
ADDR2 = (HOST, PORT2) 
BUFFSIZE = 4096 


cli = socket.socket(AF_INET, SOCK_STREAM) 
cli.connect(ADDR,) 


#Get and send IP 
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 
s.connect(("gmail.com",80)) 
ip = ((s.getsockname()[0])) 
ip = ip.encode('utf-8') 
cli.send(ip) 
print("IP Sent... \n") 

#Set received key to write to known hosts 
data = cli.recv(BUFFSIZE) 
with open('C:\cygwin\home\scollins\.ssh\known_hosts', 'w') as myfile: 
    myfile.write(str(data,'utf-8')) 
print("Key Saved To Known Hosts") 

#Close opened sockets 
s.close() 
cli.close() 


ver = socket.socket(AF_INET, SOCK_STREAM) 
ver.connect(ADDR2,) 

#Get version/build number 
if os == "Windows": 
    #Connect to the registry 
    regKey = ConnectRegistry(None, HKEY_LOCAL_MACHINE) 
    subKey = OpenKey(regKey, r"SOFTWARE\R\R Client") 
    buildno = QueryValueEx(subKey, "Version") 
else: 
    if os == "Darwin": 
     buildno = open("\Library\R\buildno") 
    else: 
     if os == "Linux": 
      buildno = open("\r\buildno") 


print("You are running software build number " + str(buildno)) 


#Receive and write server software version to file. Read file and compare build number 
data = ver.recv(BUFFSIZE) 

#THIS NEXT PRINT COMMAND RETURNS NOTHING WHICH I ASSUME IS DUE TO NOTHING BEING RECEIVED DUE TO THE BROKEN PIPE 
print(str(data)) 
with open('version.text', 'w') as myfile: 
    myfile.write(str(data,'utf-8')) 

with open('version.txt', 'r') as myfile: 
    version = myfile.read() 
print("The software on the server is version: " + version) 

if buildno in version == True: 
    print("Your sofware version is up to date") 
else: 
    print("Your software is out of date. Updating your software.") 
    os.system('') 

ver.close() 

謝謝你提供的任何幫助。

回答

1

嗯,我沒有在工作中安裝python3,但只是看着代碼,它看起來像你試圖發送一些東西與服務器端的服務器套接字。

你叫接受版本:

build,addr = ver.accept() 

然後嘗試在版本發送,而不是構建:

ver.send(version) 

通常它的工作原理是這樣的: 在服務器端,你有一個「服務器」套接字,您調用綁定然後接受,等待傳入的連接。每次客戶端連接時,接受一個套接字與此特定客戶端(「客戶端」套接字)通信。如果所有通信都通過服務器套接字進行,那麼您如何擁有多個客戶端並知道您正在「交談」的是哪一個?

代碼中的第二個錯誤是,version.read()被調用來打印值,然後再次發送它。 read()「消耗」了數據,因此第二個read()給出了一個空的結果。

此外,您應該在循環中調用send(),檢查其返回值,以確保實際發送所有數據。部分發送可能發生。

+0

謝謝你的快速回復,你100%正確。但是,我遇到了另一個問題。版本的值不是通過發送,而是接收的是一個空字節標記(b「)。可能值得注意的是,在將版本轉換爲字符串以發送它是一個元組之前。 – Metagen 2013-02-18 15:40:27

+0

不,再次看看文檔:http://docs.python.org/2/library/urllib.html 你也可以這樣做:version = urllib.urlopen(「http:// pbrcom/pa/b /latest.txt「) print(version.read()) version是文件描述符類型對象,您可以在其上執行read()以獲取數據。您試圖將對象轉換爲沒有字符串表示的字符串。 此外,不要忘記接受和upvote,如果它解決了你的問題;) – 2013-02-18 15:50:37

+0

此外,最新的time.sleep(120)? – 2013-02-18 15:53:12