0

When trying to send a file with sockets from one device on my network to another it is throttling the data to 2760 bytes and not receiving the whole file on the server side

Here is the code of my server on my raspberry pi:

import socket
import os

host = "my_ip"
port = "my_port"

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host, port))
s.listen()

def send(mess):
    con.send(bytes(mess, "utf-8"))

def receive():
    global message
    message = con.recv(22000).decode('utf-8')

while True:
    try:
        con, address = s.accept()
        print(f"Connection to {address} made successfully")
        receive()
        if message == "quit":
            break
        else:
            send("received")
            print(len(message))
            with open("file.py", 'w', encoding='utf-8')as a:
                a.write(message)
            os.system("python3 file.py")
    except:
        pass

And here is the code of my client on another device

with open('file.py', 'r', encoding = 'utf-8')as f:
    python_file = f.read()

print(len(python_file))
#returns 20940
import socket

host = "my_ip"
port = my_port

def send(mess):
    s.send(bytes(mess, 'utf-8'))
    
def receive():
    message = s.recv(1024).decode('utf-8')
    print(message)
    
while True:
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    send_it = input("Send File?[y/n]: ")
    if send_it == "y":
        try:
            s.connect((host, port))
            send(python_file)
            recieve()
        except:
            pass
    if send_it == "quit":
        try:
            s.connect((host, port))
            send(send_it)
            recieve()
        except:
            pass
    else:
        pass

When i take off the try loop it doesn't give any errors or reason as to why im only receiving part (2760 bytes) of the file. Also it will randomly(rarely) send more than 2760 bytes or it will sometimes send all the bytes. Its pretty consistently only sending 2760 bytes though.

TheAdmin
  • 78
  • 9

1 Answers1

1

Maybe you want to use sendall() instead of send(). Basically sendall() guarantees that all data will be sent unless an exception is raised and it's a python feature that is offered by other high level languages as well.

In order to receive all bytes sent, it's a good idea to do that using a loop:

data = bytearray(1)
# loop until there is no more data to receive.
while data:
   data = socket.recv(1024) # Receive 1024 bytes at a time.

There is a well explained answer on what the difference between send() and sendall() is in python here.

alexandrosangeli
  • 262
  • 2
  • 13
  • So the data variable continuously adds data to its value? When i try to print the data variable afterwards it's empty? – TheAdmin Dec 01 '20 at 22:09
  • 1
    It doesn't "add" data to its value. `data` will hold the bytes received after `socket.recv()`. When an iteration of the loop goes by, the bytes in `data` will be discarded and the next 1024 bytes (if there are that many) will be hold. Meaning you must do something with `data` inside the loop after `socket.recv()`. Try this and see if it helps. – alexandrosangeli Dec 02 '20 at 09:13
  • Thank your for the fix on looping over the data, that worked like a charm and was very relieving after two days of trial and error! – TheAdmin Dec 02 '20 at 18:30
  • This loop is never ending for me, even when data has no value it doesn't leave? – TheAdmin Dec 04 '20 at 22:48
  • @TheAdmin Try closing the socket from both parties once they are done sending/receiving. – alexandrosangeli Dec 04 '20 at 23:51
  • the problem is i can't tell when their done sending or receiving because they never leave this loop `data = bytearray(1) while data: data = con.recv(1024).decode("utf-8")`. Its like the data variable doesn't reset on the last go around after the data is all received and put into other variables. – TheAdmin Dec 05 '20 at 00:37
  • @TheAdmin Mind sharing how you solved the issue for future use of the question? – alexandrosangeli Dec 05 '20 at 10:51