Sending And Receiving Bytes through a Socket, Depending On Your Internet Speed
<p>I made a quick program that sends a file using sockets in python.</p>

<p>Server:</p>

<pre><code>import socket, threading

#Create a socket object.
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

#Bind the socket.
sock.bind( ("", 5050) )

#Start listening.
sock.listen()

#Accept client.
client, addr = sock.accept()


#Open a new file jpg file.
file = open("out.jpg", "wb")


#Receive all the bytes and write them into the file.
while True:

    received = client.recv(5)

    #Stop receiving.
    if received == b'':
        file.close()
        break

    #Write bytes into the file.
    file.write( received )
</code></pre>

<p>Client:</p>

<pre><code>import socket, threading

#Create a socket object.
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

#Connect to the server.
sock.connect(("192.168.1.3", 5050))


#Open a file for read.
file = open("cpp.jpg", "rb")

#Read first 5 bytes.
read = file.read(5)

#Keep sending bytes until reaching EOF.
while read != b'':

    #Send bytes.
    sock.send(read)

    #Read next five bytes from the file.
    read = file.read(1024)


sock.close()
file.close()
</code></pre>

<p>From experience a learn that send can send an amount of bytes that your network
speed is capble of sending them. If you give for example: sock.send(20 gb) you are going to lose bytes because most network connections can't send 20 gb at
once. You must send them part by part.</p>

<p>So my question is: How can i know the maximum amount of bytes that socket.send()
can send over the internet? How can i improve my program to send the file as quick as possible depending on my internet speed?</p>

<p><code>send</code> makes no guarantees that all the data is sent (it not directly tied to network speed; there are multiple reasons it could send less than requested), just that it lets you know how much was sent. You could explicitly write loops to <code>send</code> until it's all really sent, per <a href="http://stackoverflow.com/a/39603386/364696">Dunno's answer</a>.</p>

<p>Or you could just use <a href="https://docs.python.org/3/library/socket.html#socket.socket.sendall" rel="nofollow"><code>sendall</code></a> and avoid the hassle. <code>sendall</code> is basically the wrapper described in <a href="http://stackoverflow.com/a/39603386/364696">the other answer</a>, but Python does all the heavy lifting for you.</p>

<p>If you don't care about slurping the whole file into memory, you could use this to replace your whole loop structure with just:</p>

<pre><code>sock.sendall(file.read())
</code></pre>

<p>If you're on modern Python (3.5 or higher) on a UNIX-like OS, you could optimize a bit to avoid even reading the file data into Python using <a href="https://docs.python.org/3/library/socket.html#socket.socket.sendfile" rel="nofollow"><code>socket.sendfile</code></a> (which should only lead to partial <code>send</code> on error):</p>

<pre><code>sock.sendfile(file)
</code></pre>

<p>If the Python doesn't support <code>os.sendfile</code> on your OS, this is just a effectively a loop that <code>read</code>s and <code>send</code>s repeatedly, but on a system that supports it, this directly copies from file to socket in the kernel, without even handling file data in Python (which can improve throughput speeds significantly by reducing system calls and eliminating some memory copies entirely).</p>

python sockets