python的socket库

    技术2022-07-13  79

    python学习socket库(套接字)

    TCP:

    使用默认的方式:

    服务端:

    import socket sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.bind(('', 6969)) sock.listen(5) while True: conn, addr = sock.accept() with conn: print('Connected By:', addr) while True: try: recv_data = conn.recv(1024) if not recv_data: break print('accept mag:', recv_data.decode()) conn.sendall(recv_data) except ConnectionResetError as e: print('close using connection!') break conn.close() sock.close()

    服务端:

    import socket HOST = '192.168.41.192' PORT = 6969 sock_client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock_client.connect((HOST, PORT)) while True: msg = input('>>>>:').strip() sock_client.sendall(msg.encode()) data = sock_client.recv(1024) print('client accept msg:', data.decode())

    默认的socket是阻塞的方式

    使用非阻塞情况下:

    import socket # 同步非阻塞 HOST = '' PORT = 50007 sock = socket.socket() sock.setblocking(False) # 设置非阻塞 默认为阻塞TRUE sock.bind((HOST, PORT)) sock.listen(5) while True: try: conn, addr = sock.accept() # 没有连接会引发BlockingIOError with conn: print('Connected by:', addr) except BlockingIOError: pass

    使用非阻塞实现并发:

    import socket # 使用同步非阻塞实现服务器并发(缺点:任意一个客服端关闭,服务端会随着客服端关闭) HOST = '' PORT = 50007 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.setblocking(False) sock.bind((HOST, PORT)) sock.listen(5) client_list = [] while True: # 接受数据 try: conn, addr = sock.accept() conn.setblocking(False) # 设置这个对等数列链接为非阻塞 client_list.append((conn, addr)) print('Connected by: {}'.format(addr)) except BlockingIOError: pass # 处理请求 for client, addr in client_list: try: recv_data = client.recv(1024) if recv_data: print('接受来自:{}>>>{}'.format(addr, recv_data.decode())) client.sendall(recv_data) else: # 关闭链接 client_list.remove((client, addr)) # 从列表中删除 client.close() print('断开链接:{}'.format(addr)) except BlockingIOError: pass

    为了提高效率,使用epoll实现并发服务器:

    import socket import selectors HOST = '192.168.41.192' PORT = 50007 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.bind((HOST, PORT)) sock.listen(1) def recv(soc): try: data = soc.recv(1024) if data: print("accept data:", data.decode()) soc.send(data) else: # 删除注册 epoll_selector.unregister(soc) soc.close() except ConnectionResetError as e: print('close connection.') epoll_selector.unregister(soc) soc.close() def accept(soc): # 接受请求 conn, addr = soc.accept() print("Connected by:", addr) # 把对等链接注册到epoll监视器 epoll_selector.register( conn, selectors.EVENT_READ, recv ) # 创建一个epoll监视器 # epoll_selector = selectors.DefaultSelector() # 根据操作系统自己选择(这里是window) epoll_selector = selectors.EpollSelector() # 注册 epoll_selector.register( sock, selectors.EVENT_READ, accept ) # 循环监听 while True: # events 是一个列表 events = epoll_selector.select() # events 就是所有被触发 的事件 for key, mark in events: sock = key.fileobj callback = key.data # 执行回调函数 callback(sock)

    实现Linux定时执行脚本:

    shell脚本代码:

    #! /bin/bash pid=$(ps -ef | grep "new_server.py" | grep -w "python3") echo "pid=$pid" >> /home/app/a.log if [ "x$pid" == "x" ]; then python3 /home/app/new_server.py & fi

    需要在crontab -e打开文件

    * * * * *  sh /home/app/test.sh >/dev/null 2>&1

    Processed: 0.014, SQL: 9