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>

<blockquote>
  <p>From experience a learn that send can send an amount of bytes that
  your network speed is capble of sending them.</p>
</blockquote>

<p>Since you are using a TCP Socket (i.e. SOCK_STREAM), speed-of-transmission issues are handled for you automatically.  That is, once some bytes have been copied from your buffer (and into the socket's internal send-buffer) by the send() call, the TCP layer will make sure they make it to the receiving program, no matter how long it takes (well, within reason, anyway; the TCP layer will eventually give up on resending packets if it can't make any progress at all over the course of multiple minutes).</p>

<blockquote>
  <p>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>
</blockquote>

<p>This is incorrect; you are not going to "lose bytes", as the TCP layer will automatically resend any lost packets when necessary.  What might happen, however, is that send() might decide not to accept all of the bytes that you offered it.  That's why it is absolutely necessary to check the return value of send() to see how many bytes send() actually accepted responsibility for -- you <em>cannot</em> simply assume that send() will always accept all the bytes you offered to it.</p>

<blockquote>
  <p>So my question is: How can i know the maximum amount of bytes that
  socket.send() can send over the internet?</p>
</blockquote>

<p>You can't.  Instead, you have to look at the value returned by send() to know how many bytes send() has copied out of your buffer.  That way, on your next call to send() you'll know what data to pass in (i.e. starting with the next byte after the last one that was sent in the previous call)</p>

<blockquote>
  <p>How can i improve my program to send the file as quick as possible
  depending on my internet speed?</p>
</blockquote>

<p>Offer send() as many bytes as you can at once; that will give it the most flexibility to optimize what it's doing behind the scenes.  Other than that, just call send() in a loop, using the return value of each send() call to determine what bytes to pass to send() the next time (e.g. if the first call returns 5, you know that send() read the first 5 bytes out of your buffer and will make sure they get to their destination, so your next call to send() should pass in a buffer starting at the 6th byte of your data stream... and so on).  (Or if you don't want to deal with that logic yourself, you can call sendall() like @ShadowRanger suggested; sendall() is just a wrapper containing a loop around send() that does that logic for you.  The only disadvantage is that e.g. if you call sendall() on 20 gigabytes of data, it might be several hours before the sendall() call returns!  Whether or not that would pose a problem for you depends on what else your program might want to accomplish, if anything, while sending the data).</p>

<p>That's really all there is to it for TCP.</p>

<p>If you were sending data using a UDP socket, on the other hand, things would be very different; in the UDP case, packets can simply be dropped, and it's up to the programmer to manage speed-of-transmission issues, packet resends, etc, explicitely.  But with TCP all that is handled for you by the OS.</p>

python sockets