this is a simple socket program which has a server and some clients. clients send their texts encrypted by a simple RSA cryptography then the server side decrypts the sentence and then sends the decrypted sentence back to the client.
server:
import socket
import sys
from thread import *
from math import *
from random import *
import random
HOST = ''
PORT = 8888
size=2**16
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print 'Socket created'
#Bind socket to local host and port
try:
s.bind((HOST, PORT))
except socket.error , msg:
print 'Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
sys.exit()
print 'Socket bind complete'
#Start listening on socket
s.listen(10)
print 'Socket now listening'
def decoder(codedString,d,n):
breakcoded=[]
coded=(codedString)
#print coded;
for i in range (len(coded)):
breakcoded.append(chr(((int(coded[i])**d) % n)+48))
stri= ""
for i in range (len(breakcoded)):
stri+=breakcoded[i]
return stri
#Function for handling connections. This will be used to create threads
def clientthread(conn):
#Sending message to connected client
conn.send('Welcome to the server. Type something and hit enter\n') #send only takes string
#infinite loop so that function do not terminate and thread do not end.
while True:
#Receiving from client
data = conn.recv(1024)
## data=s.recv(size)
l = int (data)
#print l
coded=[]
i=0
data1=conn.recv(size)
print 'Recieved n: ',data1
n = int (data1)
data2=conn.recv(size)
print 'Recieved d: ',data2
d = int (data2)
for i in range (l):
data3=conn.recv(size)
#print 'Recieved: ',data3
print
coded.append(data3)
print 'coded string has been recieved....'
print ('coded string: ' , coded)
d= decoder(coded,d,n)
print d
reply = 'OK... your message decrypted as: ' + d
if not d:
break
conn.sendall(reply)
#came out of loop
conn.close()
#now keep talking with the client
while 1:
#wait to accept a connection - blocking call
conn, addr = s.accept()
print 'Connected with ' + addr[0] + ':' + str(addr[1])
#start new thread takes 1st argument as a function name to be run, second is the tuple of arguments to the function.
start_new_thread(clientthread ,(conn,))
s.close()
client:
import socket
from math import *
from random import *
host='localhost'
port=8888
size=2**16
def declare():
a = sample([5,3],2)
return (a[0],a[1])
def coder(input_message):
(p,q)=declare()
for i in range (1):
p=2**p-1
for i in range (1):
q=2**q-1
#print p
#print q
#print ("n= ",p*q)
#print a
def gcd(a,b):
if a%b==0:
return b
elif a%b > 0:
s=a%b
return gcd(b,s)
else:
raise ValueError
n=p*q
phi=(p-1)*(q-1)
e=2
while gcd(phi,e)!=1:
e+=1
d=1
while ((e*d)%phi)!=1:
d+=1
public_key=(n,e)
special_key=(n,d)
ListOfAsciis=[]
coded=[]
breakcoded=[]
for i in input_message:
ListOfAsciis.append(ord(i)-48)
for j in ListOfAsciis:
coded.append((j**e)%n)
#print ("e= ",e)
#print ("d= ",d)
#print ("coded= ",coded)
for i in coded:
breakcoded.append(chr(((i**d) % n)+48))
#print ('n= ' , n)
#print str(coded)
#print coded
return (d,n,str(coded[0]))
def decoder(codedString,d,n):
#input_d= input("please enter your private key d: ")
#input_n= input("please enter your private key n: ")
#d = int (input_d)
#n = int (input_n)
breakcoded=[]
coded=(codedString)
print coded;
for i in range (len(coded)):
breakcoded.append(chr(((int(coded[i])**d) % n)+48))
stri= ""
for i in range (len(breakcoded)):
stri+=breakcoded[i]
return stri
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
print 'socket created'
s.connect((host,port))
print 'connected'
data=s.recv(size)
print 'Recieved: ', data
while True:
input_message= raw_input("please enter your message: ")
message = list(input_message)
s.send(str(len(message)))
## (p,q)=declare()
#n=p*q
(d,n,c)=coder('i')
n=str(n)
print " ",
print " ",
print " ",
print " ",
s.send(n)
print " ",
d=str(d)
s.send((d))
print " ",
print " ",
print " ",
for i in range (len(message)):
(d,n,c)=coder(input_message[i])
print " ",
print " ",
print " ",
s.send((c))
print 'coded string has been sent to the server....'
data=s.recv(size)
print 'Recieved: ', data
now the problem is that the program sometimes works correctly and sometimes not! in false cases the server side gets two send items by the client by one recv. what should i
This is an inherent part of TCP. Stream sockets are byte streams, not message streams.
So, things are working exactly as they're supposed to. If you want to send a sequence of messages over a TCP stream, it's exactly the same problem as saving a sequence of objects to a file—you need some way of delimiting the messages. This could be as simple as using a stream of text, where newlines delimit the messages, or it could be a complex protocol, but it has to be something.
See this blog post for more detail.
Related
First off, Im a python beginner, so I'm not really experienced.
This is the code for my server - client program:
import getpass
from requests import get
import os
import thread
import socket
import sys
os.system('cls' if os.name == 'nt' else 'clear')
print '\033[91mMCP CONTROLLER\033[0m'
print ('--------------------------------------')
print ('Welcome back,' + getpass.getuser())
print ('--------------------------------------')
ip = get('https://api.ipify.org').text
print ('Your current external IP is: ' + ip)
print ('--------------------------------------')
HOST = 'localhost'
PORT = 1979
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print 'Socket created!'
try:
s.bind((HOST, PORT))
except socket.error as msg:
print 'lul'
sys.exit()
print 'Socket bind complete'
s.listen(20)
print 'Listening...'
while 1:
conn, addr = s.accept()
print 'Client connected: ' + addr[0] + ':' + str(addr[1])
msg = conn.recv(1024)
print (msg)
s.close()
print ('Please enter command')
My problem is: I want the program to stop the socket after 20 seconds and do "print('Please enter command')" whether someone connects to it or not. If I start the program now it just says "Listening..." (if I don't start the client) forever and the only option I have is to close the terminal window. But I want the program to move on after 20 seconds.
And I also want it to say some special message if it didn't get any connection after 20 seconds (like print 'no client available')
Please pardon my bad english.
As #abarnet mentioned, settimeout is probably what you want, here is an example:
import getpass
from requests import get
import os
import thread
import socket
import sys
import time
os.system('cls' if os.name == 'nt' else 'clear')
print('\033[91mMCP CONTROLLER\033[0m')
print ('--------------------------------------')
print ('Welcome back,' + getpass.getuser())
print ('--------------------------------------')
ip = get('https://api.ipify.org').text
print ('Your current external IP is: ' + ip)
print ('--------------------------------------')
HOST = 'localhost'
PORT = 1979
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print ('Socket created!')
try:
s.bind((HOST, PORT))
except socket.error as msg:
print( 'lul')
sys.exit()
print( 'Socket bind complete')
s.settimeout(5)
s.listen(20)
print ('Listening...')
while 1:
try:
conn, addr = s.accept()
msg = conn.recv(1024)
print (msg)
except socket.timeout as e:
print(e,': no connections after 5 seconds...')
s.close()
break
print( 'Client connected: ' + addr[0] + ':' + str(addr[1]))
print('please enter command:')
Use the socket.settimeout ()
s.settimeout (20);
I am currently doing a project for university, I have to create a multiple chat client and server in python 3.4.
For some reason it will connect to one client but when a second client tries to connect it does nothing. However when the first client disconnects the other client will connect to it. Does anyone have any ideas, I have been trying to work this out for over 3 hours.
The Client Server
import socket
def Main():
print("Send 'q' to exit\n")
address = str(input("ip:port -> "))
nick = input("nick: ")
try:
if address.index(":") != 0:
host = address[:address.index(":")]
port = int(address[address.index(":")+1:])
except ValueError:
host = address
port = 5000
s = socket.socket()
s.connect((host, port))
message = input("-> ")
while message != "q":
send_message = message + "pPp" + nick
send_message2 = send_message.encode("UTF-8")
s.send(bytes(send_message2))
data = s.recv(1024)
data_decoded = data.decode("UTF-8")
data2 = data_decoded
print(data_decoded)
messageServer = str(data_decoded[:data_decoded.index("pPp")])
nickServer = str(data_decoded[data_decoded.index("pPp")+3:])
if not data_decoded == data2:
print(nickServer + ": " + messageServer)
message = input("-> ")
s.close()
if __name__ == "__main__":
Main()
The server side:
import socket
import time
import os
from threading import Thread
folderPath = "Chat Logs"
filePath = folderPath + "/" + str(time.strftime("%H-%M-%S_%d-%m-%Y")) + ".txt"
def clientHandler(c):
while True:
data = c.recv(1024)
if not data:
break
data_decoded = data.decode("UTF-8")
message = str(data_decoded[:data_decoded.index("pPp")])
nick = str(data_decoded[data_decoded.index("pPp")+3:])
print(nick + "$" + message)
saveChat(nick, message)
print(" Sending: " + data_decoded)
c.send(bytes(data_decoded.encode("UTF-8")))
c.close()
def saveChat(nick, message):
if not os.path.exists(folderPath):
os.makedirs(folderPath)
if not os.path.exists(filePath):
f = open(filePath, "a")
f.close()
f = open(filePath, "a")
f.write(nick + ": " + message + "\n")
f.close()
def Main():
host = str(socket.gethostbyname(socket.gethostname()))
port = 5000
print(host + ":" + str(port) + "\n")
Clients = int(input("Clients: "))
s = socket.socket()
s.bind((host, port))
s.listen(Clients)
while True:
c, addr = s.accept()
print("Connection from: " + str(addr))
Thread(target=clientHandler(c)).start()
s.close()
if __name__ == "__main__":
Main()
You are initializing the Thread object correctly. Try one of these:
Thread(target=clientHandler, args=(c,)).start()
or
Thread(target=lambda c=c: clientHandler(c)).start()
Thread takes a callable as the target argument. Instead of passing in a callable, your code invokes the clientHandler, and passes its return value to Thread.__init__.
the changed code for server.py works for me.
what if we accept the connections in the thread handler and pass the socket object as an argument when we call the handler.
def clientHandler(s):
while True:
c, addr = s.accept()
print("Connection from: " + str(addr))
data = c.recv(1024)
if not data:
break
data_decoded = data.decode("UTF-8")
message = str(data_decoded[:data_decoded.index("pPp")])
nick = str(data_decoded[data_decoded.index("pPp")+3:])
print(nick + "$" + message)
#saveChat(nick, message)
print(" Sending: " + data_decoded)
c.send(bytes(data_decoded.encode("UTF-8")))
c.close()
In main function, I changed the following lines.
while True:
#c, addr = s.accept()
#print("Connection from: " + str(addr))
Thread(target=clientHandler(s)).start()
Here is the connection result:
>>>
10.212.245.81:5000
Clients: 3
Connection from: ('10.212.245.81', 60945)
c1$hi
Sending: hipPpc1
Connection from: ('10.212.245.81', 60976)
c2$hi
Sending: hipPpc2
Connection from: ('10.212.245.81', 61096)
c3$hi
Sending: hipPpc3
P.S I didn't try to check the code by exceeding the number of client connect requests.
Any help on how I can get this to accept more than one client, and why it isn't at the moment? Thanks!
Also, is there anything I'm doing wrong with this code? I've been following mostly Python 2 tutorials because I can't find any for Python 3.4
Here is my Server code:
import socket
import time
import os
from threading import Thread
folderPath = "Chat Logs"
filePath = folderPath + "/" + str(time.strftime("%H-%M-%S_%d-%m-%Y")) + ".txt"
def clientHandler(c):
while True:
data = c.recv(1024)
if not data:
break
data = data.decode("UTF-8")
message = str(data[:data.index("§")])
nick = str(data[data.index("§")+1:])
print(nick + ": " + message)
saveChat(nick, message)
print(" Sending: " + data)
c.send(bytes(data, "UTF-8"))
c.close()
def saveChat(nick, message):
if not os.path.exists(folderPath):
os.makedirs(folderPath)
if not os.path.exists(filePath):
f = open(filePath, "a")
f.close()
f = open(filePath, "a")
f.write(nick + ": " + message + "\n")
f.close()
def Main():
host = str(socket.gethostbyname(socket.gethostname()))
port = 5000
print(host + ":" + str(port) + "\n")
Clients = int(input("Clients: "))
s = socket.socket()
s.bind((host, port))
s.listen(Clients)
for i in range(Clients):
c, addr = s.accept()
print("Connection from: " + str(addr))
Thread(target=clientHandler(c)).start()
s.close()
if __name__ == "__main__":
Main()
And here is my Client code:
import socket
def Main():
print("Send 'q' to exit\n")
address = str(input("ip:port -> "))
nick = input("nick: ")
try:
if address.index(":") != 0:
host = address[:address.index(":")]
port = int(address[address.index(":")+1:])
except ValueError:
host = address
port = 5000
s = socket.socket()
s.connect((host, port))
message = input("-> ")
while message != "q":
s.send(bytes(message + "ยง" + nick, "UTF-8"))
data = s.recv(1024)
data = data.decode("UTF-8")
data2 = data
messageServer = str(data[:data.index("ยง")])
nickServer = str(data[data.index("ยง")+1:])
if not data == data2:
print(nickServer + ": " + messageServer)
message = input("-> ")
s.close()
if __name__ == "__main__":
Main()
First of all, I found these tutorials very helpful: BinaryTides
Here is an example of a simple tcp server that accepts multiple clients. All this one does receive data from the client and return "OK .. " + the_data. However, you could easily modify it to have a function that broadcasts the data(chat msg) to all clients connected. This example uses threading. You should google for the select module. With regards to your threads, are you sure you are a) using the right module/method for the job and b) that you are calling it in the right way?
import socket
import sys
from thread import start_new_thread
HOST = '' # all availabe interfaces
PORT = 9999 # arbitrary non privileged port
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error, msg:
print("Could not create socket. Error Code: ", str(msg[0]), "Error: ", msg[1])
sys.exit(0)
print("[-] Socket Created")
# bind socket
try:
s.bind((HOST, PORT))
print("[-] Socket Bound to port " + str(PORT))
except socket.error, msg:
print("Bind Failed. Error Code: {} Error: {}".format(str(msg[0]), msg[1]))
sys.exit()
s.listen(10)
print("Listening...")
# The code below is what you're looking for ############
def client_thread(conn):
conn.send("Welcome to the Server. Type messages and press enter to send.\n")
while True:
data = conn.recv(1024)
if not data:
break
reply = "OK . . " + data
conn.sendall(reply)
conn.close()
while True:
# blocking call, waits to accept a connection
conn, addr = s.accept()
print("[-] Connected to " + addr[0] + ":" + str(addr[1]))
start_new_thread(client_thread, (conn,))
s.close()
I've got two servers (written in python) that are nearly identical in the way they handle serial communications on the Pi. However, one works and the other one doesn't and I can't seem to find the problem. I've hooked up a logic analyzer and the first server triggers the rx/tx properly when communicating serially, however, the second server will not trigger anything.
First (working) server - cut down to show only the serial:
import socket
import sys
import RPi.GPIO as GPIO
from serial import Serial
#HOST = ' ' # Symbolic name meaning all available interfaces
PORT = 8888 # Arbitrary non-privleged port
ser = 0
#accepts a command as a string, parameters separated by white space
def processData( data ):
print ( "cmd : " + data).strip()
parseData = data.split(" ")
cmdLength = len(parseData)
cmd = parseData[0]
if cmd == "digitalWritePin":
pin = parseData[1]
state = parseData[2]
#GPIO.setup(pin, GPIO.OUT) # SHOULD HAVE ALREADY BEEN DONE W/ A CONFIG!!!
if state == '1':
GPIO.output(int(pin), True)
elif state == "0":
GPIO.output(int(pin), False)
elif cmd == "serialConfig":
baudRate = int(parseData[1])
timeOut = int(parseData[2])
global ser
ser = Serial('/dev/ttyAMA0', baudRate, timeout=timeOut)
elif cmd == "serialWrite":
serialcmd = parseData[1]
writeBuff = data.split("serialWrite")
#print writeBuff[1].strip(" ")
ser.write(writeBuff[1].strip(" "))
elif cmd == "serialReadLine":
print "serial read:"
response = ser.readline()
print response
conn.sendall(response)
print "read done"
return
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print 'Socket created'
s.bind((HOST,PORT))
print 'Socket bind complete'
s.listen(10) #parameter: backlog, controls number of connections that are 'queued'
print 'Socket now listening'
#Function f or handling connections. this will be used to create threads
def clientthread(conn):
#sending message to connected client
try:
while True:
data = conn.recv(1024)
if not data:
break
processData( data )
#out of the loop
conn.close()
except socket.error , msg:
print 'Recv failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
while 1:
#wait to accept a connection - blocking call
conn, addr = s.accept()
print 'Connected with ' + addr[0] + ':' + str(addr[1])
#start new thread takes 1st argument as a function name to be run
#second is the tuple of arguments to the function
start_new_thread(clientthread,(conn,))
s.close
the most important parts of that being:
ser = Serial('/dev/ttyAMA0', baudRate, timeout=timeOut)
and the serial config/read/write areas of the el/if block
and the second sever (that is not working):
import socket
import sys
from time import sleep
from serial import Serial
from thread import *
import binascii
#HOST = ' ' # Symbolic name meaning all available interfaces
HOST = '10.1.10.28'
PORT = 8889 # Arbitrary non-privleged port
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print 'Socket created'
try:
s.bind((HOST,PORT))
except socket.error , msg:
print 'Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
sys.exit()
print 'Socket bind complete'
s.listen(10) #parameter: backlog, controls number of connections that are 'queued'
print 'Socket now listening'
ser = Serial('/dev/ttyAMA0', baudrate = 115200, timeout= 10)
#ser.open #--- uncommenting this does not make a difference
#Function f or handling connections. this will be used to create threads
def clientthread(conn):
#infinite loop so the function does not terminate and thread does not end
try:
while True:
print "step 1"
first = conn.recv(1)
print "step 2"
if not first:
break
hextFirst = hex( ord(first) )
print hextFirst
if hextFirst == '0xff':
print "step 3"
#ser.write(hextFirst) #send 0xff (converted)
ser.write(first) #send 0xff (orignal)
length = conn.recv(1) #get length
hextLength = hex( ord(length) ) #convert length
intlength = ord(length)
print "hextLength: " + hextLength
print "step 4"
#ser.write(hextLength) #send length (converted)
ser.write(length) #send length (original)
cmd = 0
if ord(length) == 0:
cmd = conn.recv(13)
else:
cmd = conn.recv(ord(length)-2)
hextCmd = binascii.b2a_hex(cmd)
print cmd
print "hextCmd: " + hextCmd
#ser.write(hextCmd) #send cmd (converted)
ser.write(cmd) #send cmd (original)
#sleep(1)
response = ser.read(1) #get response
#hextResponse = hex(ord(response))
print "serial resp: " + response
conn.sendall(response) #send response to LV
print "step 5"
print "step 6"
sleep(10)
#out of the loop
conn.close()
except socket.error , msg:
print 'Recv failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
try:
while 1:
#wait to accept a connection - blocking call
conn, addr = s.accept()
print 'Connected with ' + addr[0] + ':' + str(addr[1])
#start new thread takes 1st argument as a function name to be run
#second is the tuple of arguments to the function
start_new_thread(clientthread,(conn,))
s.close
except KeyboardInterrupt:
ser.close
s.close
print "Exiting: Keyboard Interrupt"
I realize that is alot of code to go through, but you can ignore most of it, i'm just wondering what went wrong in the serial config/write. Like i said initially, the problem comes from the logic analyzer not seeing any serial communications (to or from) on the 2nd server, while the first server is working just fine
Try releasing /dev/ttyAMA0 from the default console by editing /boot/cmdline.txt
dwc_otg.lpm_enable=0 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 console=tty1 ..
change it to
dwc_otg.lpm_enable=0 console=tty1 .....
and removing this line from /etc/inittab
T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100
also make sure you run the program as super user sudo
I'm currently trying to write process that embeds a sequence of n IPs into packets and send it off to n server. Each server remove the outermost IP and then forward it to said IP. This is exactly like tunneling I know. During the process I also want the server to do a traceroute to where it's forwarding the packet and send that back to the previous server.
My code currently will forward the packets but it's stuck on performing the traceroute and getting it. I believe it's currently stuck in the while loop in the intermediate server. I think it's having something to do with me not closing the sockets properly. Any suggestion?
Client
#!/usr/bin/env python
import socket # Import socket module
import sys
import os
s = socket.socket() # Create a socket object
host = socket.gethostname() # Get local machine name
port = 17353 # Reserve a port
FILE = raw_input("Enter filename: \n ")
NIP = raw_input("Enter Number of IPs: ")
accepted_IP = 0
IP= []
while accepted_IP < int(NIP):
IP.append(raw_input("Enter destination IP: \n"))
accepted_IP +=1
#cIP = raw_input("Enter intemediate IP: \n ")
ipv = raw_input("Enter IP version... 4/6")
try:
s.connect((host, port))
print "Connection sucessful!"
except socket.error as err:
print "Connection failed. Error: %s" %err
quit()
raw = open(FILE,"rb")
size = os.stat(FILE).st_size
ls = ""
buf = 0
for i in IP:
while len(i) < 15:
i += "$"
ls += i
header = ipv+NIP+ls+FILE
print ls
s.sendall(header + "\n")
print "Sent header"
data = raw.read(56) +ipv + NIP + ls
print "Begin sending file"
while buf <= size:
s.send(data)
print data
buf += 56
data = raw.read(56) + ipv + NIP + ls
raw.close()
print "Begin receiving traceroute"
with open("trace_log.txt","w") as tracert:
trace = s.recv(1024)
while trace:
treacert.write(trace)
if not trace: break
trace = s.recv(1024)
print "finished forwarding"
s.close()
Intermediate server
#!/usr/bin/env python
import socket
import subprocess
srvsock = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
srvsock.bind( (socket.gethostname(), 17353) )
srvsock.listen( 5 ) # Begin listening with backlog of 5
# Run server
while True:
clisock, (remhost, remport) = srvsock.accept() #Accept connection
print
d = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
header = ""
while True:
b = clisock.recv(1)
if b == "\n":
break
header += b
num = 15 * int(header[1]) + 2
file_name = header[num:]
nheader = header[0]+ str(int(header[1])-1) + header[17:]
d.connect((socket.gethostname(), 12355))
d.sendall(nheader+'\n')
print "begin forwarding"
while True:
raw = clisock.recv(56 + num) # recieve data
ip = raw[-15:] # extract IP
ipv, NIP = raw[57] , str(int(raw[57])-1)
if NIP == "0":
while (raw):
print "stuck in this loop"
d.send(raw[:56])
raw=clisock.recv(56+num)
if not raw: break
else:
while (raw):
print raw[:57] + NIP + raw[59:-15]
print "\n"
d.send(raw[:57] + NIP + raw[59:-15])
raw = clisock.recv(56+num)
if not raw :break
print "Finish forwarding"
d.close()
break
print "Begin traceroute"
tracrt = subprocess.Popen(['traceroute','google.com'], stdout=subprocess.PIPE)
s.sendall(tracrt.communicate()[0])
print "Finished"
clisock.close()
s.close()
Destination server
import socket
s = socket.socket()
host = socket.gethostname()
port = 12355
s.bind((host,port))
s.listen(5)
while True:
csock, (client, cport) = s.accept()
print client
header = ""
while True:
b = csock.recv(1)
if b == "\n":
break
header += b
file_name = header[2:]
r = open("File_test_"+file_name,"wb")
print 'Opening file for writing'
while True:
print "Begin writing file" + " " + file_name
raw = csock.recv(56)
while (raw):
print raw
r.write(raw)
raw = csock.recv(56)
r.flush()
r.close()
print "finish writing"
break
print "closing connection"
csock.close()
s.close()
The intermediate server is stuck in clisock.recv() in this loop because the break condition not raw isn't met before the connection is closed by the client, and the client doesn't close the connection before receiving the traceroute from the intermediate server, so they are waiting on each other.
To remedy this, you might consider sending the file size to the intermediate server, so that it can be used to determine when the receive loop is done. Or, if your platform supports shutting down one half of the connection, you can use
s.shutdown(socket.SHUT_WR)
in the client after sending the file.