I found the code here: Send a file through sockets in Python (the selected answer)
But I will jut post it here again..
server.py
import socket
import sys
s = socket.socket()
s.bind(("localhost",9999))
s.listen(10)
while True:
sc, address = s.accept()
print address
i=1
f = open('file_'+ str(i)+".txt",'wb') #open in binary
i=i+1
while (True):
l = sc.recv(1024)
while (l):
print l #<--- i can see the data here
f.write(l) #<--- here is the issue.. the file is blank
l = sc.recv(1024)
f.close()
sc.close()
s.close()
client.py
import socket
import sys
s = socket.socket()
s.connect(("localhost",9999))
f=open ("test.txt", "rb")
l = f.read(1024)
while (l):
print l
s.send(l)
l = f.read(1024)
s.close()
On server code, the print l line prints the file contents..so that means that content is being transferred..
but then the file is empty??
what am i missing?
thanks
You are probably trying to inspect the file while the program is running. The file is being buffered, so you likely won't see any output in it until the f.close() line is executed, or until a large amount of data is written. Add a call to f.flush() after the f.write(l) line to see output in real time. Note that it will hurt performance somewhat.
Well that server code didn't work anyway, I've modified it to get it working.
The file was empty because it was stuck in the while True and never got around to closing the file.
Also i=1 was inside the loop so it was always writing to the same file.
import socket
import sys
s = socket.socket()
s.bind(("localhost",9999))
s.listen(10)
i=1
while True:
print "WILL accept"
sc, address = s.accept()
print "DID accept"
print address
f = open('file_'+ str(i)+".txt",'wb') #open in binary
i += 1
l = sc.recv(1024)
while (l):
f.write(l) #<--- here is the issue.. the file is blank
l = sc.recv(1024)
f.close()
sc.close()
print "Server DONE"
s.close()
Related
I initially tried using python to run but there were different errors so I tried using python3 and received the error in the title. I am trying to connect to server and download a file that has tls implemented.
import socket, ssl, pprint
import os, time
import threading
def main():
s2 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ssl_sock = ssl.wrap_socket(s2,
server_side = False,
ca_certs="CA.crt",
cert_reqs=ssl.CERT_REQUIRED)
s2.connect(('localhost',10024))
filename = raw_input("What file do you wish to download? -> ")
if filename != 'q':
s2.send(filename)
data = s2.recv(1024)
if data [:7] == 'fEXISTS':
fSize = long(data[7:])
message = raw_input("The file you wish to download is " +str(fSize)+\
"bytes, would you like to proceed? (y/n): ")
if message == 'y':
s2.send ('OK')
f = open('new_'+filename, 'wb')
data = s2.recv(2000000)
totalRecv = len(data)
f.write(data)
while totalRecv < fSize:
data = s2.recv(2000000)
totalRecv += len(data)
f.write(data)
progress = ((totalRecv/float(fSize))*100)
print ("{0: .2F}".format(progress)+\
"% Completed")
else:
print ("ERROR: File does not exist!")
s2.close()
if __name__ == '__main__':
main()
After wrapping the socket in an SSL context (with ssl.wrap_socket), you should not be using the original socket anymore.
You should be calling connect, send, recv, etc. on ssl_sock, not on s2.
(Specifically, when you call ssl.wrap_socket, the .detach method is called on the original socket which removes the file descriptor from it. The file descriptor is transferred to the SSL socket instance. The only thing you can do with the original then is close/destroy it.)
I have this simple python server-client file transfer project going on.
There are two parts to each side. First, the client sends a file to server for the first part. Server then appends a line and sends back the file to client in the second part.
My issue is that for some reason, the server code is stuck on receiving whenever I have the return file code in it. If I should comment out the second section of the code, the server receives all the file sent by client. Otherwise it freezes on receiving. And yes, client did send it.
You can ignore all the print commands, just there to see where the problem is.
servercode:
import socket
ssFT = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ssFT.bind((socket.gethostname(), 8756))
ssFT.listen(1)
while True:
(conn, address) = ssFT.accept()
text_file = 'fileProj.txt'
#Receive, output and save file
with open(text_file, "wb") as fw:
print("Receiving..")
while True:
print('receiving')
data = conn.recv(1024)
print('Received: ', data.decode('utf-8'))
if not data:
print('Breaking from file write')
break
fw.write(data)
print('Wrote to file', data.decode('utf-8'))
fw.close()
print("Received..")
#Append and send file
print('Opening file ', text_file)
with open(text_file, 'ab+') as fa:
print('Opened file')
print("Appending string to file.")
string = b"Append this to file."
fa.write(string)
fa.seek(0, 0)
print("Sending file.")
while True:
data = fa.read(1024)
conn.send(data)
if not data:
break
fa.close()
print("Sent file.")
break
ssFT.close()
client code:
import socket
csFT = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
csFT.connect((socket.gethostname(), 8756))
text_file = 'passphrase.txt'
#Send file
with open(text_file, 'rb') as fs:
#Using with, no file close is necessary,
#with automatically handles file close
while True:
data = fs.read(1024)
print('Sending data', data.decode('utf-8'))
csFT.send(data)
print('Sent data', data.decode('utf-8'))
if not data:
print('Breaking from sending data')
break
fs.close()
#Receive file
print("Receiving..")
with open(text_file, 'wb') as fw:
while True:
data = csFT.recv(1024)
if not data:
break
fw.write(data)
fw.close()
print("Received..")
csFT.close()
I tested your code locally with Python 3.
The problem that I saw was with conn.recv in the server code. Because of the conn.recv blocks the connection and it is waiting for more data.
The solution that I found was sending commands to server informing about BEGIN and END of the data transfer, like that:
client.py
#Send file
with open(text_file, 'rb') as fs:
#Using with, no file close is necessary,
#with automatically handles file close
csFT.send(b'BEGIN')
while True:
data = fs.read(1024)
print('Sending data', data.decode('utf-8'))
csFT.send(data)
print('Sent data', data.decode('utf-8'))
if not data:
print('Breaking from sending data')
break
csFT.send(b'ENDED') # I used the same size of the BEGIN token
fs.close()
server.py
with open(text_file, "wb") as fw:
print("Receiving..")
while True:
print('receiving')
data = conn.recv(32)
if data == b'BEGIN':
continue
elif data == b'ENDED':
print('Breaking from file write')
break
else:
print('Received: ', data.decode('utf-8'))
fw.write(data)
print('Wrote to file', data.decode('utf-8'))
fw.close()
print("Received..")
Client.py complete code:
https://pastebin.com/LySsgEe4
Server.py complete code:
https://pastebin.com/KADZpqkM
I hope to help!
The way I solved this same issue is by sending the file size first, then the server can stop waiting as soon as it receives the whole file. I dunno whether there is a better solution or not but this works like a charm:
BUFFER_SIZE = 1024
client.py
import os
fsize = os.path.getsize(text_file)
csFT.send(str(fsize).encode('utf-8'))
with open(text_file, 'rb') as fs:
data = fs.read(BUFFER_SIZE)
while data:
csFT.send(data)
data = fs.read(BUFFER_SIZE)
server.py
with open(text_file, 'wb') as fw:
msg = ssFT.recv(BUFFER_SIZE)
fsize = int(msg.decode('utf-8'))
rsize = 0
while True:
data = ssFT.recv(BUFFER_SIZE)
rsize = rsize + len(data)
fw.write(data)
if rsize >= fsize:
print('Breaking from file write')
break
I am currently working on a program of mine to try to send two csv files from my raspberry pi (client) to my laptop (server). In addition, I need to write two different sets of data to the two different csv files. The first one is raw data which will continue to write in data every 30 seconds and another is averaging of the raw data every 15 mins)
My first question is: Is it possible to do the above task? Or do I need to write two different servers and clients codes? (Refer to both codes below). Can I combine both of them? So that it can write two different data (raw and averaging) to two different csv file at the same time.
My second question is: How do I append new sets of data without rewriting the entire file (I tried append before and it duplicates the file data over and over again).
Client.py (This code currently only sends one csv file which is the raw data)
import time
import socket
TCP_IP = '192.168.1.105'
TCP_PORT = 5005
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((TCP_IP, TCP_PORT))
f = open('sensingdata.csv', 'rb')
print 'Sending...'
l = f.read(1024)
while (l):
print 'Sending...'
s.send(l)
l = f.read(1024)
print "Done Sending"
time.sleep(30)
Server.py
import socket
import sys
TCP_IP = ""
TCP_PORT = 5005
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((TCP_IP, TCP_PORT))
s.listen(5)
while True:
conn, addr = s.accept()
f = open('sensing1.csv', 'wb')
print "Got connection from", addr
print "Receiving..."
l = conn.recv(1024)
while (l):
print "Receiving Data..."
f.write(l)
l = conn.recv(1024)
print "Done Receiving"
f.close()
conn.close()
Client2.py (This code is for the appending of averaging data)
import time
import socket
TCP_IP = '192.168.1.105'
TCP_PORT = 5005
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((TCP_IP, TCP_PORT))
g = open('average.csv', 'rb')
print 'Sending Averaging Data...'
l = f.read(1024)
while (l):
print 'Sending...'
s.send(l)
l = g.read(1024)
print "Done Sending"
time.sleep(900)
Server2.py
import socket
import sys
import csv
TCP_IP = ""
TCP_PORT = 5005
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((TCP_IP, TCP_PORT))
s.listen(5)
while True:
conn, addr = s.accept()
g = open('average.csv', 'ab')
print "Got connection from", addr
print "Receiving Averaging Data..."
l = conn.recv(1024)
for rows in g:
while (l):
if row not in rows:
print "Receiving Averaging Data..."
g.write(l)
l = conn.recv(1024)
print "Done Receiving"
g.close()
conn.close()
I am trying to send a file over a tcp socket in a peer to peer chat system coded in python. The receiving socket seems not to know that there is no more file to receive. The only way I can get the receiving socket to not anticipate the data that isn't coming is by closing the sending socket (using socket.shutdown(socket.SHUT_WR)). However, closing the sending socket is not an option because I need that socket to send other messages. I fisrt tried allocating a new port for file sending/receiving and failed. Now, I have tried creating an end of file "signal" but it does not get recognized on the receiving end as a message separate from the tcp segment, so I am stuck.
The sending code looks like this:
def sendFile(self,filePath):
try:
f = open(filePath, 'rb')
print 'file opened'
for soc in self.allClients.keys():
try:
f = open(filePath, 'rb')
except:
print "File does not exist"
print 'Sending File: ' + filePath
l = f.read(1024)
while (l):
print 'Sending...'
soc.send(l)
l = f.read(1024)
soc.send('end')
f.close()
print 'File sent'
except:
print "File does not exist"
the receiving code looks like this:
def receiveFile(self, ext, clientsoc):
f = open('receivedFile' + ext,'wb')
print "Receiving File..."
l = clientsoc.recv(1024)
while(l):
print "Receiving..."
if (l is not 'end'):
f.write(l)
print l + '\n'
l = clientsoc.recv(1024)
else:
break
f.close()
print "Received Fileeeeeooooo"
Even more strange, this code works when I am using it outside of my peer programme. Any help would be greatly appreciated, I have been struggling with this for two days now.
First of all, you must not compare strings with is or is not:
>>> a = "he"
>>> a + "llo" is "hello"
False
Second, TCP is a streaming protocol. recv is getting up to 1024 bytes, but could be less, and if you send two pieces from your server, they can be merged into one recv. So l is not likely to be "end" but "last bytes of the file's end". And if you check for "end", "end" is not allowed to be in the file. Best solution is to send the length of the file first, and then send and recv length bytes.
PS: you probably want to use sendall at the server side.
Sending the file size first worked!!
New code looks like this.
Sending code:
def sendFileOrImage(self,path):
name, ext = os.path.splitext(path)
filesize = str(os.path.getsize(path))
message = filesize + ',' + ext
print 'message'
for client in self.allClients.keys():
client.send(message)
self.sendFile(path)
def sendFile(self,filePath):
try:
f = open(filePath, 'rb')
except:
print "File does not exist"
print 'Sending File: ' + filePathty
for soc in self.allClients.keys():
l = f.read(1024)
while (l):
print 'Sending...'
soc.send(l)
l = f.read(1024)
f.close()
print 'File sent'
Receiving code:
def receiveFile(self,ext, filesize, clientsoc):
total = 0
f = open('receivedFile' + ext,'wb')
print "Receiving File..."
l = clientsoc.recv(1024)
total = len(l)
while(l):
print "Receiving..."
f.write(l)
if (str(total) != filesize):
print 'trying to receive'
l = clientsoc.recv(1024)
total = total + len(l)
else:
break
f.close()
print "Received Fileeeeeooooo"
Thanks everyone for the help!
Your receiving code works but still there is a problem you need to fix real quick. If your filesize is under 1024, your socket will keep listening for ever and in order to fix this problem you need to change your code like below.
def receiveFile(self,ext, filesize, clientsoc):
total = 0
f = open('receivedFile' + ext,'wb')
print("Receiving File...")
l = clientsoc.recv(1024)
total = len(l)
while(l):
print("Receiving...")
f.write(l)
if (str(total) != filesize):
print 'trying to receive'
l = clientsoc.recv(1024)
total = total + len(l)
if(int(total)>= int(filesize)):
break
f.close()
print("Received Fileeeeeoooo")
I am trying to receive an image in python to use it in my program.
Here is the sever code:
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(("127.0.0.1", 5005))
server_socket.listen(5)
data = ' '
client_socket, address = server_socket.accept()
print "Conencted to - ",address,"\n"
while (1):
data = client_socket.recv(1024)
print "The following data was received - ",data
print "Opening file - ",data
img = open(data,'r')
while True:
strng = img.readline(512)
if not strng:
break
client_socket.send(strng)
img.close()
print "Data sent successfully"
exit()
#data = 'viewnior '+data
#os.system(data)
And here is the client code:
import socket,os
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect(("127.0.0.1", 5005))
size = 1024
while(1):
print "Enter file name of the image with extentsion (example: filename.jpg,filename.png or if a video file then filename.mpg etc) - "
fname = raw_input()
client_socket.send(fname)
#fname = 'documents/'+fname
fp = open(fname,'w')
while True:
strng = client_socket.recv(512)
if not strng:
break
fp.write(strng)
fp.close()
print "Data Received successfully"
exit()
#data = 'viewnior '+fname
#os.system(data)
The received should now be read to be able to use it. I am opening it like this:
input_image = Image.open('data').convert('L').resize((100, 100))
but when I run both codes in cmd the output is:
The following data was received - + path Opening file - + path
Then nothing happens although the image should be used and the final output should be shown.
Anyone can help?
I don't know if this is your (only) problem, but when working with binary files, you should pass the b flag to the built-in function open:
img = open(data, 'rb')