2009-07-08 75 views
7

我需要清空套接字上的数据(确保没有任何东西可以接收)。 不幸的是,在python套接字模块中没有这个功能。如何在python中清空套接字?

我已经实现的东西是这样的:

def empty_socket(sock): 
    """remove the data present on the socket""" 
    input = [sock] 
    while 1: 
     inputready, o, e = select.select(input,[],[], 0.0) 
     if len(inputready)==0: break 
     for s in inputready: s.recv(1) 

你觉得呢?有没有更好的方法来做到这一点?


更新:我不想更改套接字超时。这就是为什么我喜欢选择阅读。


更新:原来的问题是使用'冲洗'的术语。看起来'空'是一个更好的术语。


更新 - 2010-02-27: 我注意到一个错误时,该货币对已经关闭。输入准备始终充满插座。我通过添加最大数量的循环来解决这个问题。有更好的解决办法吗?

+0

这不是每个人都说的“同花顺”。查看文档中用于阅读套接字的示例。 http://docs.python.org/library/socket.html#example – JimB 2009-07-08 13:33:11

+1

您是否考虑过使用Twisted代替您的程序?如果你这样做,你永远不需要做这样的事情。 Twisted会立即将​​所有数据从套接字中提取出来,并在任何时候将它们传递给您,因此您不需要混淆像Thomas的答案中所述的select()问题那样的难看的细节。 – Glyph 2009-07-09 11:19:33

+0

@Glyph:不,我不认为Twisted是因为我想使用标准的python模块来避免外部依赖。感谢这个评论,我会看看扭曲,也许重新考虑我的选择 – luc 2009-07-09 11:42:32

回答

6

如果用“flush”表示抛弃任何未决的传入数据,那么您可以像使用select一样使用select(),也可以将套接字设置为非阻塞并读取一个循环,直到数据不足。

还要注意的是(从Linux手册页):

在Linux下,选择()可能会报告套接字文件描述符为“准备 阅读”,而不过随后的读取块。这个 可能例如发生在数据到达时,但是 检查有错误的校验和并被丢弃。可能有其他 情况,其中文件描述符虚假地报告为 就绪。因此,在应该不会阻塞的套接字上使用O_NONBLOCK可能更安全。

Spurious readiness notification for Select System call

正如已被他人注意, “刷新”,通常是指输出。

-1

不知道这是否会工作,但你可以一个文件对象附加到套接字的文件描述符,并调用该文件对象的flush()方法:

import os 

file_obj = os.fdopen(your_socket.fileno()) 
file_obj.flush() 

这不会在Windows中工作,因为描述符由fileno()返回不能传递到os.fdopen()在Windows中

1

使用select.select是良好的做法,如Socket Programming HOWTO所示。您需要使用sock.setblocking(0)将套接字设置为非阻塞。

只是关于命名的评论:flush通常与输出操作有关。

1

对于UDP数据包,我做了以下内容:

  1. 创建套接字,设置选项,并结合后,我用socket.settimeout()。注意setblocking()的文档给出了一些信息,其中settimeout()不是 - 如果你希望你的套接字操作被阻塞,你应该使用settimeout()来设置超时。 setblocking()只是将无限超时放在上面。 (我不得不打电话settimeout()随后setblocking(1)的错误。)

  2. 我的“缓冲区清空”功能则只是这(“监听器”是我的插座):

    def FlushListen(self): while 1: try: PacketBytes = self.__Listener.recv(1024) except: break;

    随着1超时其次,这将读取所有UDP数据包,然后在没有数据后返回1秒。

对我来说,我使用它只是两个程序之间在同一台PC上说话,所以我可以很容易地降低我超时,但速度不是问题,所以我很好这一点。

根据其他人发布的一些链接,这也应该适用于数据流。

0

不能,我们只是继续阅读,直到缓冲区为空?

def clear_buffer(sock): 
    try: 
     while sock.recv(1024): pass 
    except: 
     pass