Reputation: 77
Is there a method to wait for a result from an SSL socket before continuing?
for example this is my current code :
circ_to_rend.createStream(1, "xx.x.x.x", 80)
connected = recvCell(ssl_sock)
but is there a way to pause the program until something is sent back from that stream or do I just simply carry on using the code above which should do this as connected willn't be assigned a value until somthing is received?
create stream is a section of code i have written which creates a stream to send data through the tor network,and recvCell is below, this gets a reply and decodes it so it can be read :
def recvCell(sock, waitFor = 0):
while True:
hdr = sock.recv(3)
circid, cmd = struct.unpack(">HB", hdr[0:3])
ln = 509
if cmd == 7 or cmd >= 128:
ln = struct.unpack(">H", sock.recv(2))[0]
pl = sock.recv(ln)
print "got pkt circ ",circid, " cmd", cmd
if cmd == waitFor or waitFor == 0:
print "Return pkt circ ",circid, " cmd", cmd
return { 'circId': circid, 'cmd': cmd, 'len': ln, 'pl': pl}
Upvotes: 0
Views: 206
Reputation: 366013
To answer your literal question:
is there a way to pause the program until something is sent back from that stream
Yes, the select
module (or, in 3.4+, the higher-level selectors
module) provides ways to pause until something has been sent back, after which you know you can receive it without blocking.
But there's a much simpler way to do this, and as far as I can tell you're already doing it:
do I just simply carry on using the code above which should do this as connected willn't be assigned a value until somthing is received?
If connected
isn't assigned a value until something is received, then you're already pausing the program until something is sent back from the stream. Unless you switch a socket to non-blocking mode, recv
automatically does that. So… I don't know what your problem is, but if you're looking for validation that your code is correct, then yes, it is—at least in this aspect.
There is at least one other problem, however. There is absolutely no guarantee that recv(509)
will block until 509 bytes come in. It will block until any packet comes in. Which could be less than 509 bytes. Which means your code will read the first, say, 300 bytes of a message and treat it as a whole message, and then the next time you try to recv
you'll get the remaining 209 bytes of that message (or maybe those 209 bytes plus the first 140 of the next message, or whatever) and confuse your code badly. You should always loop and accumulate until you get the full data. The easiest way to do that is to write a function like this:
def recvall(sock, bufsize):
buf = ''
while len(buf) < bufsize:
newbuf = sock.recv(bufsize - len(buf))
if not newbuf:
return buf # or maybe raise an exception
buf += newbuf
Upvotes: 0
Reputation: 31524
The code you provided is not complete so we can't figure out the entire design, but the ssl
module uses socket
, whose recv()
method can:
(socket in blocking mode): Blocks the execution until some data is ready.
(socket in non-blocking mode): Throws an error if no data is available
The sockets are created in blocking mode as default (the blocking setting can be changed using setblocking). So a call to recv()
should block until some data is ready on the SSL socket.
Upvotes: 1