Question

I'm writing a TCP client/server and I've been hitting this broken pip error in the latter part of the code. I have been unable to isolate the cause due to a limited understanding of Python and socket programming and I am, therefore, unable to fix the problem. I'm going to have to include all the code as there might be some sort of conflict causing this issue that I am unaware of, sorry for the long post.

I have marked where I encounter the issue below, everything up to this point runs fine.

Server Code:

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)

Client Code :

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()

Thank you for any help provided.

Was it helpful?

Solution

Well, I don't have python3 installed here at work, but just from looking at the code, it looks like you are trying to send something with the server socket in the server part.

You call accept on ver:

build,addr = ver.accept()

Then you try to send on ver, instead of build:

ver.send(version)

Usually it works like this: On the server side, you have a "server" socket, that you call bind on and then accept, waiting for incoming connections. Every time a client connects, accept yields a socket to talk to this specific client ("client" socket). If all communication would go via the server socket, how could you have multiple clients and know which one you are "talking" to?

The second error in the code was, that version.read() was called to print the value and later again to send it. read() "consumes" the data, thus the second read() gave an empty result.

Also, you should call send() in a loop, checking its return value, to make sure all of the data is actually sent. Partial sends can happen.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top