等待使用套接字

时间:2014-08-12 10:18:35

标签: python sockets

是否有方法在继续之前等待SSL套接字的结果?

例如这是我当前的代码:

circ_to_rend.createStream(1, "xx.x.x.x", 80)
connected = recvCell(ssl_sock)

但是有没有办法暂停程序,直到从该流发送回来的东西,或者我只是继续使用上面的代码应该这样做,因为连接将不会分配一个值,直到收到somthing?

create stream是我编写的一段代码,它创建了一个通过tor网络发送数据的流,而recvCell位于下方,这得到一个回复​​并对其进行解码以便可以读取:

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}

2 个答案:

答案 0 :(得分:1)

您提供的代码不完整,因此我们无法弄清楚整个设计,但ssl模块使用socket,其recv()方法可以:

  1. 阻塞模式下的套接字):阻止执行,直到某些数据准备就绪。

  2. 套接字处于非阻塞模式):如果没有可用数据则引发错误

  3. 默认情况下,套接字以阻止模式创建(阻止设置可以使用setblocking更改)。因此,对recv()的调用应该阻塞,直到SSL套接字上的某些数据准备就绪。

答案 1 :(得分:0)

回答你的字面问题:

  

有没有办法暂停程序,直到从该流发送回来的内容

是的,select模块(或者,在3.4+中,更高级别的selectors模块)提供了暂停的方法,直到某些内容被发送回来,之后你知道你可以收到它阻塞。

但是这样做的方法要简单得多,据我所知,你已经做过了:

  

我只是继续使用上面的代码来执行此操作,因为连接将不会被分配值直到收到somthing?

如果connected在收到某些内容之前未分配值,则您暂停该程序,直到从该流发回某些内容为止。除非您将套接字切换到非阻塞模式,否则recv会自动执行此操作。所以...我不知道你的问题是什么,但是如果你正在寻找验证你的代码是正确的,那么是的,至少在这方面是这样。


然而,至少还有一个问题。绝对不能保证recv(509)将阻塞直到509个字节进入。它将阻塞直到任何数据包进入。这可能少于509个字节。这意味着您的代码将读取消息的第一个,比如300个字节并将其视为整个消息,然后在您下次尝试recv时,您将获得该消息的剩余209个字节(或者可能是那209个字节加上下一个消息的前140个,或者其他什么)并且严重混淆了你的代码。您应始终循环并累积,直到获得完整数据。最简单的方法是编写一个这样的函数:

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
相关问题