File transferring, File can't be opend after transfer - python

I am currently working on a file transfer server and ran into
a problem. I am able to transfer the file completly and it works perefect,
But when the client that received the file cannot open it through python.
What I mean is that if I transferr a file, I can see it in the dic of the client the received it, but it cannot open it and I get an:IOError that the file doesn't exist.
The server:
def download_manager(self, sock, ADDR, name):
sock.send('Starting file download: '+name)
# Getting the socket that has the file
# Getting the user ip address
BUFSIZ = 1024
fileSock = socket(AF_INET, SOCK_STREAM)
fileSock.connect(ADDR)
print 'connected;'
# Starting the file request protocol.
tries = "2"
# sending number of retries.
fileSock.send(tries + "," + name)
sock.send(tries)
for i in range(int(tries)):
# Accepting the start message.
data, size = fileSock.recv(BUFSIZ).split(',')
sock.send(size)
size = int(size)
if data == 'Start':
fileSock.send('ok')
# Getting first data from the supplier.
data = fileSock.recv(BUFSIZ)
# Sending the data to the request client.
sock.send(data)
current_size = BUFSIZ
while current_size <= size:
# Getting data from the supplier.
data = fileSock.recv(BUFSIZ)
# The server "sleeps" in order to keep a synchronization between the client and the server.
# The client works slower than the server(It needs to save the file as well.
time.sleep(0.0001)
# Sending the data to the request client.
sock.send(data)
current_size += BUFSIZ
print current_size
# Receive for the request client the end message.
#sock.send(data)
data = sock.recv(1024)
if data == 'ok':
fileSock.send(data)
break
else:
fileSock.send(data)
else:
sock.send("wrong")
fileSock.close()
The sender client, Just the relevant part:
print "connection from:", addr
# From here on, the server works by the File-Transfer RFC.
# Accepting number of retries from the server and the name of the file.
data = clientsock.recv(self.BUFSIZ)
tries, name = data.split(',')
# Opening File.
f = file(name, mode='rb')
if not tries:
clientsock.close()
continue
try:
for i in range(int(tries)):
# Sending the file size.
clientsock.send('Start,'+str(self.file_size(name)))
# Accepting an ok.
ok = clientsock.recv(self.BUFSIZ)
if not ok:
continue
if ok == "ok":
# Sending the file.
clientsock.send(f.read(-1))
# Waiting for confirmation.
ok = clientsock.recv(self.BUFSIZ)
if ok == "ok":
break
else:
continue
f.close()
except IOError as e:
f.close()
print e
# An error has occurred, closing the socket.
#clientsock.send('End,None')
clientsock.close()
The recieve Client:
def get_file(self, name):
"""
This function receives and saves the requested file from the server.
:param name: The name of the file( How it is saved )
:return: None.
"""
name = name.split('.')
tries = int(self.sock.recv(self.BUFSIZ))
progress = 0
for i in range(tries):
f = file(name[0] + '.' + name[1], mode='wb')
final_size = int(self.sock.recv(self.BUFSIZ))
data = self.sock.recv(self.BUFSIZ)
f.write(data)
current_size = self.BUFSIZ
while current_size <= final_size:
progress = (float(current_size)/final_size)
if progress > 0.01:
self.app.progress = progress
data = self.sock.recv(self.BUFSIZ)
f.write(data)
current_size += self.BUFSIZ
f.close()
print "Current: " + str(current_size)
print "real: " + str(self.file_size(name[0] + '.' + name[1]))
print "Wanted: " + str(final_size)
self.app.progress = None
if self.file_size(name[0] + '.' + name[1]) == final_size:
print 'ok'
self.sock.send('ok')
break
else:
print 'Bad'
os.remove(name[0] + '.' + name[1])
self.sock.send('Bad')
continue
Any Help is welcomed!

Related

How to transfer more files rather than just one using python?

I made a file transferrer and the problem is that out of unknown reason it lets me only send one file... When I try the second time the program works fine, but the file doesn't show up in directory. It would mean a lot to me if someone helped me out.
Code for sender:
import os
import shutil
import socket
import time
# Creating a socket.
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind((socket.gethostname(), 22222))
sock.listen(5)
print("Host Name: ", sock.getsockname())
# Accepting the connection.
client, addr = sock.accept()
original = ""
print("When you want to stop with file uploading type -> STOP <-")
while (1):
original = input(str("Filepath:"))
if (original!="STOP"):
filename = os.path.basename(original)
target = r'C:\Users\Gasper\Desktop\transfer\filename'
path = target.replace('filename', filename)
new_file = shutil.copy(original, path)
# Getting file details.
file_name = filename
file_size = os.path.getsize(file_name)
# Sending file_name and detail.
client.send(file_name.encode())
client.send(str(file_size).encode())
# Opening file and sending data.
with open(file_name, "rb") as file:
c = 0
# Running loop while c != file_size.
while c <= file_size:
data = file.read(1024)
if not data:
break
client.sendall(data)
c += len(data)
os.remove(filename)
else:
break
print("File Transfer Complete!")
input("Press enter to exit...")
# Closing the socket.
sock.close()
Code for receiver:
import socket
import time
host = input("Host Name: ")
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Trying to connect to socket.
try:
sock.connect((host, 22222))
print("Connected Successfully")
except:
print("Unable to connect")
exit(0)
# Send file details.
file_name = sock.recv(100).decode()
file_size = sock.recv(100).decode()
# Opening and reading file.
with open("./rec/" + file_name, "wb") as file:
c = 0
# Starting the time capture.
start_time = time.time()
# Running the loop while file is recieved.
while c <= int(file_size):
data = sock.recv(1024)
if not data:
break
file.write(data)
c += len(data)
# Ending the time capture.
end_time = time.time()
print("File transfer Complete!")
input("Press enter to exit...")
# Closing the socket.
sock.close()
Example:
Filepath: C\Users\Admin\Desktop\Directory\File1.txt(I put in the first file path and it transfers successfully)
Filepath: C\Users\Admin\Desktop\Directory\File2.txt(I put in the second file path and it doesnt transfer at all)

File Server Upload Python

File Server Download Problem Python 2.5.1
So i am working on a File Server as a hobby project. I am having some problems though. I can use the client to successfully upload the file to the server but say the file to upload is 50,000 bytes (50 mbs) it will only upload like 49,945 bytes then if i try opening it, it says its corrupt. If i close the server it goes to 50,000 then works. Is there a way to fix this without the server needing to close and reopen?
(Downloading Doesnt Have this Problem)
Full Client Code:
Client
Full Server:
Server
Client Upload Function:
def Uploader(s):
IsReal = True
data = "UploaderReady"
if data == "UploaderReady":
List = []
FilePath = dir_path = os.path.dirname(os.path.realpath(__file__))
List.append(os.listdir(FilePath))
FileUpload = raw_input("Pick a file? -> ")
for Item in List:
if FileUpload == Item:
IsReal = True #checks if item exists
if IsReal == True:
File = open(FileUpload,'rb')
bytestosend = File.read(1024)
FileSize = os.path.getsize(FileUpload)
s.send(FileUpload)
s.send(str(FileSize))
s.send(bytestosend)
while bytestosend != "":
bytestosend = File.read(8192)
s.send(bytestosend)
print"Processing"
File.close()
time.sleep(1.5)
s.send("COMPLETE")
print"File Successfully Uploaded"
time.sleep(2)
print" \n " * 10
Main()
if IsReal == "False":
print"Item doesn't Exist"
time.sleep(2)
print" \n " * 10
s.close()
Main()
Server Upload Function:
Todo = sock.recv(1024)
if Todo == "U":
print str(addr)+" Uploading"
UploadingThread = threading.Thread(target=Uploader,args=(c,c,))
UploadingThread.start()
def Uploader(c,s):
filename = s.recv(1024)
filesize = s.recv(1024)
f = open(filename,'wb')
totalRecv = 0
while totalRecv < filesize:
FileContent = s.recv(8192)
totalRecv += len(FileContent)
f.write(FileContent)
print"Download Complete"
f.close()
s.close()
You close the client connection on the server side, but never close it on the client side as Cory Shay said.
Instead of closing it though, you need to shutdown the socket and signal it is done writing with s.shutdown(socket.SHUT_WR)
Here's how it should look for the client:
def Uploader(s):
IsReal = True
data = "UploaderReady"
if data == "UploaderReady":
List = []
FilePath = dir_path = os.path.dirname(os.path.realpath(__file__))
List.append(os.listdir(FilePath))
FileUpload = raw_input("Pick a file? -> ")
for Item in List:
if FileUpload == Item:
IsReal = True #checks if item exists
if IsReal == True:
File = open(FileUpload,'rb')
bytestosend = File.read(1024)
FileSize = os.path.getsize(FileUpload)
s.send(FileUpload)
s.send(str(FileSize))
s.send(bytestosend)
while bytestosend != "":
bytestosend = File.read(8192)
s.send(bytestosend)
print"Processing"
s.shutdown(socket.SHUT_WR) # End the writing stream
print(s.recv(1024)) # Expecting the server to say 'upload complete'
s.close() # close the socket
File.close()
time.sleep(1.5)
s.send("COMPLETE")
s.close() #To close connection after uploading
print"File Successfully Uploaded"
time.sleep(2)
print" \n " * 10
Main()
and the server:
def Uploader(c,s):
filename = s.recv(1024)
filesize = s.recv(1024)
f = open(filename,'wb')
totalRecv = 0
while totalRecv < filesize:
FileContent = s.recv(8192)
totalRecv += len(FileContent)
f.write(FileContent)
s.send("Upload Complete!") # Tell client the upload is complete
print"Download Complete"
f.close()
s.close() # Close the socket
Also, you are passing the server Uploader 2 identical arguments, and only using one, instead you should just pass one:
UploadingThread = threading.Thread(target=Uploader,args=(c,c,))
# should be
UploadingThread = threading.Thread(target=Uploader,args=(c,))
Similarly, your password thread only needs 2:
c, addr = s.accept()
print"Client Connection: <"+str(addr)+">"
PasswordThread = threading.Thread(target=Password,args=(c,addr))
def Password(c,addr):
c.send("WAITINGPASSWORD")
PASSWORD = "123"
password = c.recv(1024)
and your checking password function can be simpler:
def Password(c,addr):
password = "123"
c.send("WAITINGPASSWORD")
attempt = c.recv(1024)[::-1]
if attempt == password:
doStuff()

How to make the server side socket code run continuously

I have a server/client socket program that is used to transfer a file from the client to the server. The issue is that the code stops running once the file is transferred. I want to change it such that the server side code is continuously running so that I can transfer a file multiple times without having to run the code again and again
Server code:
import socket
host = ''
port = 5560
def setupServer():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print("Socket created.")
try:
s.bind((host, port))
except socket.error as msg:
print(msg)
print("Socket bind comlete.")
return s
def setupConnection():
s.listen(1) # Allows one connection at a time.
conn, address = s.accept()
print("Connected to: " + address[0] + ":" + str(address[1]))
return conn
def storeFile(filePath):
picFile = open(filePath, 'wb')
print(filePath)
print("Opened the file.")
pic = conn.recv(1024)
#print(pic)
while pic:
print("Receiving picture still.")
picFile.write(pic)
pic = conn.recv(1024)
picFile.close()
def dataTransfer(conn):
# A big loop that sends/receives data until told not to.
while True:
# Receive the data
data = conn.recv(1024) # receive the data
data = data.decode('utf-8')
# Split the data such that you separate the command
# from the rest of the data.
dataMessage = data.split(' ', 1)
command = dataMessage[0]
if command == 'GET':
reply = GET()
elif command == 'REPEAT':
reply = REPEAT(dataMessage)
elif command == 'STORE':
print("Store command received. Time to save a picture")
storeFile(dataMessage[1])
reply = "File stored."
elif command == 'LED_ON':
callLED()
reply = 'LED was on'
else:
reply = 'Unknown Command'
# Send the reply back to the client
conn.sendall(str.encode(reply))
#print("Data has been sent!")
conn.close()
s = setupServer()
while True:
try:
conn = setupConnection()
dataTransfer(conn)
except:
break
The client side code is below:
import socket
from time import sleep
from time import time
host = '192.168.0.17'
port = 5560
data = "hi"
filepath = "/var/www/html/unknown.txt"
def setupSocket():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
return s
def sendPic(s, filePath):
print(filePath)
pic = open(filePath, 'rb')
chunk = pic.read(1024)
s.send(str.encode("STORE " + filePath))
t = time()
while chunk:
print("Sending Picture")
s.send(chunk)
#print(chunk)
chunk = pic.read(1024)
pic.close()
print("Done sending")
print("Elapsed time = " + str(time() - t) + 's')
#s.close()
return "Done sending"
def sendReceive(s, message):
s.send(str.encode(message))
reply = s.recv(1024)
print("We have received a reply")
print("Send closing message.")
s.send(str.encode("EXIT"))
#s.close()
reply = reply.decode('utf-8')
return reply
def transmit(message):
s = setupSocket()
response = sendReceive(s, message)
return response
def backup(filePath):
s = setupSocket()
response = sendPic(s, filePath)
return response
while True:
backup(filepath)
print("Backup Complete!")
break
I do not own the code. I have made some change to the code that I got from a YouTube video.
Have you had a look at the SocketServer module?
You could setup your dataTransfer() function as the handle() method of a RequestHandler class, then start your server with the serve_forever() method.

Sending, receiving with python socket

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.

python socket send files

trying out a new way to send files. The client will be run every 10 mins to ask server to send what's new in last 10 mins. What I have so far work 40% of the time. I can't figure out so far why that is the case.
server main loop:
while 1:
conn, addr = s.accept()
last_ai = get_last_sent_ai()
new_ai = get_new_ai(last_ai)
ai_notes = ''
''' send # of file '''
print "sending length ---------"
conn.sendall('{0}'.format(len(new_ai)))
for ai_file in new_ai:
ai_file = ai_file.rstrip()
if not os.path.isfile(ai_file): continue
f = open(ai_file, 'rb')
ai_notes = f.read()
f.close()
print "sending file infor " + '{0:<10d}:{1:>40s}'.format(len(ai_notes), ai_file)
ready_flag = conn.recv(5)
if ready_flag == "Ready":
conn.sendall(ai_notes)
if len(new_ai) > 0:
update_last_sent(new_ai[-1])
else:
print 'nothing to send'
conn.sendall(' ')
conn.close()
s.close()
Client main loop:
if num_f == 0: sys.exit(0)
while num_f > 0:
f_info = ''
f_info = s.recv(50)
f_len,f_name_tmp = f_info.split(':')
f_len = int(f_len)
s.sendall("Ready")
f_name = f_name_tmp
f = open(f_name, 'wb')
recvd = 0
while recvd < f_len:
chunk = s.recv(min(f_len - recvd, 1024))
if chunk == '':
raise RuntimeError("socket connection broken")
f.write(chunk)
recvd = recvd + len(chunk)
f.close()
num_f -= 1
s.close()
update:
the issue seems to be gone after I went back and changed how the send and receive are done. There gotta be some kind of blocking going on when it hangs, so I followed the python doc and modified the code and all the tests so far are working.

Categories