Reputation: 406
I have a TCP handling streams of data. It takes 4096 bytes at a time, but I need a way to find out the whole socket size before it recv. This is so I can determine how many times the socket will be read before it switches socket. It will also notify that this is the last recv of this socket so that I can do something with it before select switches to the other socket when it becomes available.
def handle_tcp(self, sock, remote):
fdset = [sock, remote]
while True:
r, w, e = select.select(fdset, [], [])
# How to find out how much bytes need to be read from socket?
if sock in r:
non_blocking_calculation()
if remote.send(sock.recv(4096)) <= 0: break
if remote in r:
non_blocking_calculation()
if sock.send(remote.recv(4096)) <= 0: break
Upvotes: 2
Views: 7557
Reputation: 347
You beated me to it. In accordance with Igor Kalinosvkiy way. You can either Use FIONREAD to do this or use MSG_PEEK and keep reading until empty. For example, after select()
.
import fcntl, termios, array, math
...
sock_size = array.array('i', [0]) # initialise outside While loop
if sock in r:
fcntl.ioctl(sock, termios.FIONREAD, sock_size)
count = ceil(sock_size[0] / float(BUF_SIZE))
print("Socket size: {} and count: {}".format(sock_size[0], count)
Upvotes: 4
Reputation: 1262
Linux and Windows have FIONREAD(synonym SIOCINQ) ioctl for that.
Python has limited ioctl's support in socket and fcntl modules but in usual TCP programming such ioctl's are not widely used. Usually you just setblocking(false) and read all available data until BlockingIOError raises. Ore define some kind of messages with headers/markers specifying size/bounds.
Upvotes: 2