Python Select socket非阻塞写日志

上一篇我们通过线程锁实现了一个简单的并发写日志功能,该篇我们通过socket来实现一个写日志的程序,代码如下:

socket服务端

import selectors
import socket, time

sel = selectors.DefaultSelector()

def accept(sock, mask):
    conn, addr = sock.accept()
    conn.setblocking(False)
    sel.register(conn, selectors.EVENT_READ, read)

lastPre = ''

def read(conn, mask):
    global lastPre
    try:
        data = conn.recv(1024)
    except ConnectionResetError as e:
        print('检测到客户端在发送数据时异常退出,服务端关闭该连接', conn)
        sel.unregister(conn)
        conn.close()

    if data:
        data = data.decode('utf-8')
        dataList = data.strip(';').split(';')
        if lastPre != '':
            dataList[0] = lastPre + str(dataList[0])

        if data.endswith(';'):          
            lastPre = ''
        else:
            lastPre = str(dataList[-1])
            dataList = dataList[:-1]

        for d in dataList:
            # 写日志功能自己实现,日志是否写成功不需要返回,所以我们注释掉try..except段代码
            time.sleep(1)
            text = d + " is completed successfully"
            print(text)         
            #try:
                #conn.send(bytes(text, encoding='utf-8'))
            #except ConnectionResetError as e:
                #print('服务端发送数据时客户端异常退出,服务端关闭该连接', conn)
                #sel.unregister(conn)
                #conn.close()           

    else:
        print('客户端正常退出,服务端关闭该连接', conn)
        sel.unregister(conn)
        conn.close()


def server():
    sock = socket.socket()
    sock.bind(('localhost', 1234))
    sock.listen(100)
    sock.setblocking(False)
    sel.register(sock, selectors.EVENT_READ, accept)

    while True:
        events = sel.select()
        for key, mask in events:
            callback = key.data
            callback(key.fileobj, mask)

if __name__ == '__main__':
    server()

socket.send只能发送bytes类型的数据,所以我们需要在服务端自己按照预定的规则来处理数据,比如我们split(‘;’)。
socket.sendfile可以一个文件对象。
另外socket默认使用tcp协议,即SOCK_STREAM,也可以改为udp协议,即SOCK_DGRAM。
具体细节,大家多参考官方文档

socket客户端

import socket

def client():
    addr = ('127.0.0.1', 1234)  
    s = socket.socket()
    s.connect(addr)
    for i in range(30):
        text = "测试" + str(i) + ";"
        s.send(bytes(text, encoding="utf-8"))
        #data = s.recv(1024)
        #print(data)

def mulClient():
    socks = []
    addr = ('127.0.0.1', 1234)
    for i in range(10):
        socks.append(socket.socket())

    for s in socks:
        s.connect(addr)

    for i in range(10):
        for s in socks:
            text = "Socket"+ str(socks.index(s)) + "-" + str(i)+ ";"
            s.send(bytes(text, encoding="utf-8"))           
            #data = s.recv(1024)
            #print(data)

if __name__ == '__main__':
    mulClient()
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页