如何在python中清空套接字?

问题描述 投票:9回答:5

我需要清空套接字上的数据(确保没有东西可以接收)。不幸的是,在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:我已经注意到该对关闭时的一个错误。 inputready总是用套接字填充。我通过添加最大数量的循环来修复它。有更好的解决方案吗?

python sockets select
5个回答
6
投票

如果通过“flush”意味着丢弃任何挂起的传入数据,那么您可以像使用select()一样使用select,或者将套接字设置为非阻塞并在循环中读取,直到您没有数据为止。

另请注意(来自Linux手册页):

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

Spurious readiness notification for Select System call

正如其他人所指出的,“冲洗”通常指的是输出。


2
投票

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

-1
投票

不确定这是否可行,但您可以将文件对象附加到套接字的文件描述符并在该文件对象上调用flush()方法:

import os

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

这在Windows中不起作用,因为fileno()返回的描述符无法传递给Windows中的os.fdopen()

© www.soinside.com 2019 - 2024. All rights reserved.