VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > temp > python入门教程 >
  • 03网络编程从之异步服务器

# 这里异步服务器的实现是借助于select,有关select模块在我上边的博客中有体现。
# zen_utils也是我们自己写的一个脚本。也在上边的磨课中

import select, zen_utils,queue,time

def serve(listener,inpouts,outputs,message_queues):
    while inputs:
        print('等待开始第一个线程连接1111')
        # 开始select监听,对input_list中的服务器端的server开始进行监听
        # 一旦调用socket的send,recv函数,将会再次调用此模块
        # 这里监控三个参数,第一个返回的是可读的list, 第二个存储的是可写的list, 第三个存储的是错误信息的
        readable, writeable, errorinfo = select.select(inputs, outputs, inputs)
        # 这里判断的是有没有客户端进行连接。
        for s in readable:
            # 然后在进行判断是服务端触发的连接还是客户端触发的链接。
            if s is listener:
                # 接收的消息和客户端的IP端口
                print(s)
                connection, client_address = s.accept()
                print('client:', connection, client_address)
                # 设置为非阻塞模式。
                connection.setblocking(0)
                # 将客户端连接也加入到inputs监听列表中。
                inputs.append(connection)
                # 加入到要发送的消息队列中。
                message_queues[connection] = queue.Queue()
            else:
                # 这是客户端发送消息触发的请求。
                data = s.recv(1024)
                if data != b'?' and data != b'':
                    print('客户端{}发送了{}消息', s.getpeername(), data.decode('utf-8'))
                    # 将接收到的消息需要进行回复的答案。放到对应的消息队列中。
                    print(zen_utils.aphorisms.get(data,b''))
                    message_queues[s].put(zen_utils.aphorisms.get(data,b''))
                    if s not in outputs:
                        outputs.append(s)
                else:
                    print("一个客户端断开了连接", client_address)
                    # 输出端不在监听。
                    if s in outputs:
                        outputs.remove(s)
                    # 输入端不再监听
                    inputs.remove(s)
                    # 关闭这个套接字。
                    s.close()
                    # 删除消息队列中的消息
                    del message_queues[s]
        # 下边是处理输出。
        for s in writeable:
            try:
                message_queue = message_queues.get(s)
                sent_data = ''
                if message_queue is not None:
                    # 如果消息队列为空,不阻塞
                    sent_data = message_queue.get_nowait()
                else:
                    # 这里触发的客户端关闭连接。
                    print('客户端关闭连接')
            except queue.Empty:
                # 客户端发送完了消息。
                print('%s' % s.getpeername())
                outputs.remove(s)
            else:
                if sent_data != '':
                    s.sendall(sent_data)
                else:
                    print('客户端关闭连接')

            # 处理异常情况。
            for s in errorinfo:
                print('有一个异常客户端的连接', s.getpeername())
                inputs.remove(s)
                if s in outputs:
                    outputs.remove(s)
                s.close()
                del message_queues[s]
        time.sleep(1)

if __name__ == '__main__':
    address = zen_utils.parse_command_line('获取IP端口')
    listener = zen_utils.create_srv_socket(address)
    # 将定义好的一个套接字传入到列表中。
    inputs = [listener]
    # 处理要发送的数据。
    outputs = []
    # 要发送的数据
    message_queues = {}
    serve(listener,inputs,outputs,message_queues)

出处:https://www.cnblogs.com/cong12586/p/14094069.html

相关教程