仅当 Python 套接字中可用时才接收数据

Moh*_*d M 6 python sockets tcp

我只想接收可用的数据。就像Serial.available()在Arduino中一样。我想要这样的代码:

if there is data:
     receive and print
else:
     print 'No data'
Run Code Online (Sandbox Code Playgroud)

事实上,我不希望程序仅仅因为接收数据而停止。

Mar*_*nen 8

您可以调用.setblocking(False)套接字来禁用阻塞模式。当调用BlockingIOError否则会阻塞时,它将引发 a 。.accept()但是,当您或.recv()在套接字上没有准备好连接或没有数据可接收时,您必须处理异常。

例如:

try:
    data = s.recv(1024)
    print(data)
except BlockingIOError:
    print('no data')
Run Code Online (Sandbox Code Playgroud)

select.select可用于轮询多个套接字以获取数据。这是一个简单的例子:

try:
    data = s.recv(1024)
    print(data)
except BlockingIOError:
    print('no data')
Run Code Online (Sandbox Code Playgroud)

两个客户端连接、发送内容然后断开连接的示例:

import socket
import select

server = socket.socket()
server.bind(('', 8000))
server.listen()
readables = [server] # list of readable sockets.  server is readable if a client is waiting.
i = 0
while True:
    # to_read will be a list of sockets with readable data
    to_read, to_write, errors = select.select(readables, [], [], 0)
    for sock in to_read: # iterate through readable sockets
        if sock is server: # is it the server?
            client, address = server.accept()
            print(f'\r{address}: connected')
            readables.append(client) # add the client
        else:
            # read from address client
            data = sock.recv(1024)
            if not data:
                print(f'\r{sock.getpeername()}: disconnected')
                readables.remove(sock)
                sock.close()
            else:
                print(f'\r{sock.getpeername()}: {data}')
    # a simple spinner to show activity
    i += 1
    print(r'/-\|'[i%4], end='\r', flush=True)
Run Code Online (Sandbox Code Playgroud)