Send a file through sockets in Python
You must put all the code from sc, address = s.accept()
upto sc.close()
into another loop or the server simply terminates after receiving the first file. It doesn't crash, the script is just finished.
[EDIT] Here is the revised code:
import socket
import sys
s = socket.socket()
s.bind(("localhost",9999))
s.listen(10) # Accepts up to 10 connections.
while True:
sc, address = s.accept()
print address
i=1
f = open('file_'+ str(i)+".pdf",'wb') #open in binary
i=i+1
while (True):
# receive data and write it to file
l = sc.recv(1024)
while (l):
f.write(l)
l = sc.recv(1024)
f.close()
sc.close()
s.close()
Note that s.listen(10)
means "set maximum accept rate to 10 connections", not "stop after 10 connections".
Python 3: Sending files through socket. (Client-Server Program)
I've made few minimal adjustments to your code with which it runs as so that server.py
continuously listens on a given port and sends back data which each invocation of client.py
asks for.
server.py
#!/usr/bin/env python3
import socket
import os
import sys
def Main():
host = '127.0.0.1'
port = 50001
s = socket.socket()
s.bind((host,port))
print("server Started")
s.listen(1)
while True:
c, addr = s.accept()
print("Connection from: " + str(addr))
filename = ''
while True:
data = c.recv(1024).decode('utf-8')
if not data:
break
filename += data
print("from connected user: " + filename)
myfile = open(filename, "rb")
c.send(myfile.read())
c.close()
if __name__ == '__main__':
Main()
client.py
#!/usr/bin/env python3
import socket, os.path, datetime, sys
def Main():
host = '127.0.0.1'
port = 50001
s = socket.socket()
s.connect((host, port))
Filename = input("Type in ur file ")
s.send(Filename.encode('utf-8'))
s.shutdown(socket.SHUT_WR)
data = s.recv(1024).decode('utf-8')
print(data)
s.close()
if __name__ == '__main__':
Main()
And now a bit of explanation.
On the server side. The outer loop accepts a connection, then reads from the connection until done (more on this later). Prints your debugging info, but note you were trying to print
the file object and not the filename (which would fail trying to concatenate). I also open the file in binary mode (that way I can skip the str
-> bytes
translation.
On the client side. I've added closing the writing end of the socket when the file has been sent. Note you might want to use sendall
instead of send
for this use case: check those docs links for details. And I've added a print
for the incoming data.
Now that bit with shutting down the writing end in the client and the inner loop reading (and also related to the sendall
hint. Which BTW also holds true for the server side, otherwise you should loop, as you might see your content truncated; other option is to also have a sending loop.). Stream sockets will guarantee you get your bytes in in order you've send them. On itself it has no idea whether your message is complete and it also does not guarantee in how many and how large chunks will the data be sent and received (resp.).
The inner loop of server keep reading until we see an EOF
(we've receive zero length string in python socket
). This would happen (be returned by recv
when the remote socket (or at least its writing end) has been shut down. Since we still want to reuse the connection, we only do that on the sending end in the client. Hope this helps you to move ahead.
sending file through socket in python 3
You are closing the server connection before the client read the “done”
Send big file over socket
Check the return value of send
and recv
. The 9000000
value is a maximum but not guaranteed value to send/recv. Alternatively, use sendall
.
For recv
, you have to loop until you receive all the data. If you close the socket after the file is sent, recv
will return zero when all the data is received.
FYI, your while True:
in both files never loops due to the break
, so they are unnecessary.
Here's something that should work...
server.py
import socket
soc = socket.socket()
soc.bind(('',8080))
soc.listen(1)
print('waiting for connection...')
with soc:
con,addr = soc.accept()
print('server connected to',addr)
with con:
filename = input('enter filename to send: ')
with open(filename, 'rb') as file:
sendfile = file.read()
con.sendall(sendfile)
print('file sent')
client.py
import socket
soc = socket.socket()
soc.connect(('localhost',8080))
savefilename = input("enter file name to receive: ")
with soc,open(savefilename,'wb') as file:
while True:
recvfile = soc.recv(4096)
if not recvfile: break
file.write(recvfile)
print("File has been received.")
How to send zip file using Python sockets?
There were several issues with your code. For example, when reading the zip (binary) file, you should read it as bytes, not as string, and send it as bytes. Also, your server needs to know in advance the expected file size to be able to read the file in chunks. You can do that using byte ordering. Below is a working example. Credits go to this for the data receiving approach, which was slightly modified to read the data in chunks, as your code requires.
EDIT: The server has been modified to support reconnection from the client. Thus, client = s.accept()
has been moved to inside the while loop and client's connection gets closed after the file has been received.
server.py
import sys
import socket
HOST = sys.argv[1] if len(sys.argv) > 1 else '0.0.0.0'
PORT = int(sys.argv[2] if len(sys.argv) > 2 else 5555)
SIZE = 1024
BYTEORDER_LENGTH = 8
FORMAT = "utf-8"
s = socket.socket()
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((HOST, PORT))
s.listen(1)
while True:
client = s.accept()
print(f"\033[33m[*] Listening as {HOST}:{PORT}\033[m")
print(f"\033[32m[!] Client connected {client[1]}\033[m")
print(f"Sending 'copy trash' msg")
client[0].send('copy trash'.encode())
print(f"[RECV] Receiving the file size")
file_size_in_bytes = client[0].recv(BYTEORDER_LENGTH)
file_size= int.from_bytes(file_size_in_bytes, 'big')
print("File size received:", file_size, " bytes")
client[0].send("File size received.".encode(FORMAT))
print(f"[RECV] Receiving the filename.")
filename = client[0].recv(SIZE).decode(FORMAT)
print(f"[RECV]Filename received:", filename)
client[0].send("Filename received.".encode(FORMAT))
print(f"[RECV] Receiving the file data.")
# Until we've received the expected amount of data, keep receiving
packet = b"" # Use bytes, not str, to accumulate
while len(packet) < file_size:
if(file_size - len(packet)) > SIZE: # if remaining bytes are more than the defined chunk size
buffer = client[0].recv(SIZE) # read SIZE bytes
else:
buffer = client[0].recv(file_size - len(packet)) # read remaining number of bytes
if not buffer:
raise Exception("Incomplete file received")
packet += buffer
with open(filename, 'wb') as f:
f.write(packet)
print(f"[RECV] File data received.")
client[0].send("File data received".encode(FORMAT))
client[0].close()
s.close()
client.py
import sys
import socket
import subprocess
import shutil
import os
HOST = sys.argv[1] if len(sys.argv) > 1 else '127.0.0.1'
PORT = int(sys.argv[2] if len(sys.argv) > 2 else 5555)
FORMAT = "utf-8"
SIZE = 1024
BYTEORDER_LENGTH = 8
s = socket.socket()
s.connect((HOST, PORT))
msg = s.recv(SIZE).decode()
print('[*] server:', msg)
if(msg.lower() == "copy trash"):
#shutil.make_archive("/root/trashcopy", 'zip', "/root/.local/share/Trash")
shutil.make_archive("_trashcopy", 'zip', "Trash")
file_size = os.path.getsize('_trashcopy.zip')
print("File Size is :", file_size, "bytes")
file_size_in_bytes = file_size.to_bytes(BYTEORDER_LENGTH, 'big')
print("Sending the file size")
s.send(file_size_in_bytes)
msg = s.recv(SIZE).decode(FORMAT)
print(f"[SERVER]: {msg}")
print("Sending the file name")
s.send("trashcopy.zip".encode(FORMAT))
msg = s.recv(SIZE).decode(FORMAT)
print(f"[SERVER]: {msg}")
print("Sending the file data")
with open ('_trashcopy.zip','rb') as f1:
s.send(f1.read())
msg = s.recv(SIZE).decode(FORMAT)
print(f"[SERVER]: {msg}")
s.close()
Related Topics
Replacing Values in a Dataframe for Given Indices
Convert String to Python Class Object
How to Test Multiple Variables for Equality Against a Single Value
Suppress Stdout/Stderr Print from Python Functions
Subtract One Dataframe from Another Excluding the First Column Pandas
Change a Colour of a Pixel in Python
No Unique Mode; Found 2 Equally Common Values
Finding Index of an Item Closest to the Value in a List That'S Not Entirely Sorted
Pip3: Command Not Found But Python3-Pip Is Already Installed
How to Make Print() Accept the User Input in Same Line
Truth Value of a Series Is Ambiguous. Use A.Empty, A.Bool(), A.Item(), A.Any() or A.All()
Calculating Manhattan Distance in Python in an 8-Puzzle Game
Python: Import Cx_Oracle Importerror: No Module Named Cx_Oracle Error Is Thown
What Is the Most Pythonic Way to Check If Multiple Variables Are Not None
Conditional Row Read of CSV in Pandas
How to Merge Elements in List in Python With Condition
How to Extract the Entire Row and Columns When Condition Met in Numpy Array
Winerror 10049: the Requested Address Is Not Valid in Its Context