Socket.sendall is very handy for sending. It would be nice if there was a socket.recvall. Unfortunatelty, receiving data is hard. One way to to do a recvall, is to use timeouts that get reset if any amount of data arrives. Useful, if you know almost nothing about what you are receiving.
Another, if you can control the sender, is to use a sentinal or marker, and send when the end has arrived.
This example, shows a really simple way, to do that. The assumption is that you have a unique enough string as an end marker. You pass a socket to either of these functions. The sender takes on the end marker and the receiver looks for it.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
End='something useable as an end marker' def send_to_end(sock,data): #assume the data is appendable, may need to stringify the data sock.sendall(data+End) def recvall2(the_socket): #instead of doing #data=the_socket.recv(8192) #return data total_data=;data='' while True: #if recv returns 0 bytes, other side has closed data=the_socket.recv(8192) if End in data: total_data.append(data[:data.find(End)]) break total_data.append(data) if len(total_data)>1: #check if end_of_data was split last_pair=total_data[-2]+total_data[-1] if End in last_pair: total_data[-2]=last_pair[:last_pair.find(End)] total_data.pop() break result=''.join(total_data) return result
I haven't seen any examples of a generic way to receive a lot of data by sending and looking for an end marker.
This way of doing is simple -- just put an end marker at the end of the data you are sending. If I get around to it, I'll change it to take account of the, hopefully very rare with a unique enough marker, situation where the data duplicates the end marker(oops).