Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Socket. How to receive all data with socket.recv()?

I have a problem with receiving data from server to client. I have the following client-side function that attempts to receive data from the server. The data sent by the server using the socket.sendall (data) function is greater than buff_size so I need a loop to read all the data.

def receiveAll (sock):
    data = ""
    buff_size = 4096
    while True: 
       part = sock.recv (buff_size)
       data + = part
       if part <buff_size:
          break;
    return data

The problem that occurs to me is that after the first iteration (read the first 4096mb), in the second the program is blocked waiting for the other data in part = sock.recv (buff_size). How do I have to do so that recv() can continue reading the other missing data? Thank you.

like image 295
Nico Rossello Avatar asked Mar 11 '23 04:03

Nico Rossello


1 Answers

Your interpretation is wrong. Your code reads all the data that it get from the server. It just doesn't know that it should stop listening for incoming data. It doesn't know that the server sent everything it had.

First of all note that these lines

if part <buff_size:
      break;

are very wrong. First of all you are comparing a string to int (in Python3.x that would throw an exception). But even if you meant if len(part) <buff_size: then this is still wrong. Because first of all there might be a lag in the middle of streaming and you will only read a piece smaller then buff_size. Your code will stop there.

Also if your server sends a content of the size being a multiple of buff_size then the if part will never be satisfied and it will hang on .recv() forever.

Side note: don't use semicolons ;. It's Python.


There are several solutions to your problem but none of them can be used correctly without modyfing the server side.

As a client you have to know when to stop reading. But the only way to know it is if the server does something special and you will understand it. This is called a communication protocol. You have to add a meaning to data you send/receive.

For example if you use HTTP, then a server sends this header Content-Length: 12345 before body so now as a client you know that you only need to read 12345 bytes (your buffer doesn't have to be as big, but with that info you will know how many times you have to loop before reading it all).

Some binary protocols may send the size of the content in first 2 or 4 bytes for example. This can be easily interpreted on the client side as well.

Easier solution is this: simply make server close the connection after he sends all the data. Then you will only need to add check if not part: break in your code.

like image 198
freakish Avatar answered Mar 12 '23 17:03

freakish