I wrote a function to send a file using a socket. It sends first the size of the file and then sends blocks of 9999 bytes to the client until the file ends. the problem is when the server reads the file, the file ends too fast. for example, for a file with 180,000 bytes, it ends after 2 blocks. I couldn't understand why this happens and I tried to run the read on this file in the terminal and it worked fine but here it doesn't. As much as I know the problem is supposed to be in the sever because when I checked, the server doesn't send all the data he is supposed to send because after about 2 read()
calls it returns an empty string even though most of the file haven't been read.
here is the server code:
MAX_LENGTH_OF_SEND = 9999
def send_file(path, client_socket):
"""send a file to the client. if succeeded return success, else return error massage
:param path: path of the file to send
:param client_socket: the socket of the client to send to
:return: if success return 'success sending a file' else, return error massage
"""
try:
size = os.stat(path).st_size
print(size)
# send the length of the file to the client
send(str(size), client_socket)
read = 0
with open(path, "rb") as file1:
massage = file1.read(MAX_LENGTH_OF_SEND)
read += MAX_LENGTH_OF_SEND
while read < size:
binary_send(massage, client_socket)
massage = file1.read(MAX_LENGTH_OF_SEND)
read += MAX_LENGTH_OF_SEND
print(f"The file {path} has been sent")
except Exception as e:
print(f"Couldn't send file because {e}")
return "Error: " + str(e)
return "success sending a file"
def send(msg, client_socket):
""" sending a massage to a client by sending the length of the massage first
:param msg: the massage to send
:param client_socket: the client to send the massage
"""
client_socket.send(str(len(msg)).encode())
client_socket.send(msg.encode())
def binary_send(msg, client_socket):
""" sending a massage to a client by sending the length of the massage first without encoding the massage
:param msg: the massage to send
:param client_socket: the client to send the massage
"""
print(f"len = {str(len(msg)).encode()}")
client_socket.send(str(len(msg)).encode())
client_socket.send(msg)
Here is the client code:
data = receive_msg(my_socket)
if data.startswith("Error:"):
print(data)
else:
if SENT_PICTURE_PATH.endswith("\\"):
path = SENT_PICTURE_PATH + request[1]
else:
path = SENT_PICTURE_PATH + "\\" + request[1]
if not os.path.exists(path):
os.makedirs(path)
with open(path, "wb") as file:
size = int(data)
given = 0
error = False
while not error and given < size:
length = int(my_socket.recv(4).decode())
print(length)
data = my_socket.recv(length)
print(data)
try:
if data.decode().startswith("Error:"):
error = True
print(data.decode())
except UnicodeDecodeError or ValueError:
pass
if not error:
file.write(data)
size += length
def receive_msg(my_socket):
"""receive a massage from the server with a length of 99 max
:param my_socket: the socket to get from
:return: the massage
"""
length = int(my_socket.recv(2).decode())
return my_socket.recv(length).decode()