python select 设置超时时间,过了一会,没有返回

新手上路,请多包涵

我在写一个网络服务器,centos, 跟多台客户端进行交互,使用select模型,程序在跑了一段时间之后,突然在select那里卡住了,明明socket 是establish状态,上面也应该有数据包过来,但是select并没有返回。不确定是select机制有问题,还是其他原因,代码:

ip="x.x.x.x"
port1 = 8322
server = socket.socket()
server.setblocking(False)
server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
server.bind((ip,port1));
server.listen(10)
cli_socket = socket.socket()
cli_socket.setblocking(False)
host = "127.0.0.1"
port2 = 12355
cli_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
cli_socket.bind((host, port2))
cli_socket.listen(5)
inputs=[server,cli_socket,]
while True:
readable, writable, exceptional = select.select(inputs, outputs, inputs, 30)
for s in readable:
    if s is server:
        conn,address = server.accept()
        rec_buf=conn.recv(1024)
        //make some handle here, store this connection in global data
        conn.setblocking(0)
        conn.sendall("pass")
        inputs.append(conn)
    elif s is cli_socket:
        cli_conn, addr = s.accept()
        command = cli_conn.recv(1024)
        ret=command.split(',')
            if ret[0] == "OPEN":                                                
                total_key[ret[1]].conn_sock.sendall("open")
                cli_conn.send("success")
                cli_conn.close()
    else:
        rec_buf=s.recv(1024)                                        
        //make some handle here                        
        s.sendall("ok")
for s in exceptional:
    inputs.remove(s)
    s.close()
阅读 5.6k
1 个回答

有很多小问题,比如

1        conn,address = server.accept()
2        rec_buf=conn.recv(1024)
3        //make some handle here, store this connection in global data
4        conn.setblocking(0)
5        conn.sendall("pass")

第 2 行将阻塞整个线程,直到对方发送数据,或连接断开。
第 5 行因为没有预先判断 conn 是否可写,操作可能失败。

建议使用 asyncio 改写,参考

# -*- coding: utf-8 -*-
import asyncio


async def handle_server(reader, writer):
    data = await reader.readexactly(10)
    print('recv1: {}'.format(data.decode()))
    writer.write('pass'.encode())
    writer.close()


async def handle_client(reader, writer):
    data = await reader.readexactly(4)
    if data.decode() == 'OPEN':
        writer.write('success'.encode())
    writer.close()


def new_listener(loop, ip, port, handler):
    coro = asyncio.start_server(handler, ip, port, loop=loop)
    return loop.run_until_complete(coro)


if __name__ == "__main__":
    loop = asyncio.get_event_loop()
    new_listener(loop, '127.0.0.1', 8322, handle_server),
    new_listener(loop, '127.0.0.1', 12355, handle_client),
    loop.run_forever()
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题