0

I am trying to stop recv from waiting endlessly for input.

First I tried:

recv = bytes('','UTF-8')

while True:
    data_recv = self.socketclient.recv(1024*768)
    if not data_recv:
        break

    else:
        recv += data_recv

return recv

On Serverside I send a picture and then the server just waits after host.sendall(string). So I thought after a couple of receives (since the picture is bigger the client has to receive more often) it will detect data_recv == false and stops but it doesn't happen.

My second try was with select()

do_read = False
recv = bytes('','UTF-8')

while True:
    read_sockets,write_sockets,error_sockets = select.select([self.socketclient],[],[])
    do_read = bool(read_sockets)
    print (do_read)
    if do_read:
        print ("read")
        data_recv = self.socketclient.recv(640*480)
        recv += data_recv
    else:
        break

return recv

With this he only reads True from print(do_read) and then also just stops and waits endlessly. Here too I had expected to read False at some point.

So my question is how do I manage it, that my client reads the entire string from the socket and if nothing is send anymore it stops?

I had some success with self.socketclient.settimeout() but I rather would not use it since it will always waste time in the programm and it is more like a workaround.

Mrob
  • 281
  • 4
  • 16

1 Answers1

1

You have to stop your while loop when all data is received. So after each recv you have to check if received data length is the length of file you requested. If it is, then you break the loop and do something with that data.

recv has no knowledge if sending of data is done, because it doesn't know how long data is. It is just listening forever until you or other endpoint close connection.

You can also use non-blocking socket (which is better by the way).

Rafał Łużyński
  • 7,083
  • 5
  • 26
  • 38
  • Ok so maybe I don't understand what select() does. I thought that if there is data in my socket it will return true and if not, it will return false. So If all the data has been send, `bool(read_sockets)` will return false the next step and then exit the while loop through the brake command. Isn't that how it works? – Mrob May 21 '15 at 13:02
  • select returns data if there is received data, if there is no data it waits until data is received, but only for a blocking-socket. If you will use nonblocking socket it will return no data which should evaluate to False. To switch to nonblocking socket, pass `0` as timeout. – Rafał Łużyński May 21 '15 at 14:08
  • That doesn't seem to work. I have tried `self.socketclient.setblocking(0)` and also `self.socketclient.settimeout(0)`. I also put the host side which sends the images to sleep to make sure it doesn't send any more data. But still my receiving side won't recognize the end of sending and won't leave the loop. – Mrob May 21 '15 at 15:07
  • 1
    I wrote that to make sure all data is sent you have to check length of your recv variable. In example if you want to get a file that has 1kb, then server that is sending this file has to send you size of that file (or send some terminating line) so you can know when to stop waiting for data. recv don't get al data at once. even if you set recv to 1024*768 it can load only 2 bytes, so you have to wait until you get all 1024*768 bytes, tehn break the loop. – Rafał Łużyński May 21 '15 at 15:15
  • I got good results with sending the lengths of data and breaking the loop after my recv has the same lengths. However if I send the picture it has always the same size because the format of the webcam is always the same (I also checked it -> 920120). So I say `if len(recv) == 920120 break` The first couple of time it works. But then somehow he doesn't reach EXACTLY the lenghts. So he doesn't break. So I guess it would be best to send a terminating line. Do you have a nice and simple way of doing so? – Mrob May 27 '15 at 16:45
  • Then don't check the exact size. Just check` if len(recv) >= 920120` and take only bytes you need. so if you have already 980 Bytes, but you are waiting for 1000, and in next step you receive another 40 Bytes, then you have 1020. But those last 20 Bytes are not part of your image, it must be something different (if you are sure that image has 1000 Bytes). So from those last received 40 Bytes take only those you need - 20. – Rafał Łużyński May 28 '15 at 09:48
  • If the other side sends one image after another then the 20 bytes would be the first 20 bytes of the next image. – BlackJack Jun 02 '15 at 15:19