基于socket.select 实现的回写服务端代码---python版本

基于select的IO多路复用实现的回写服务
客户端用线程池模拟了多个客户端同时请求时场景

代码比较简单,直接上代码

  • 服务端代码
# -*- coding:utf-8 -*-
"""
File Name: select_svr
Author: 82405
Data: 2022/6/2 13:27
-----------------------
Info:
    基于select实现的回写服务
-----------------------
Change Activity:
    2022/6/2: create
"""
import socket
import select
import queue

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(('127.0.0.1', 1234))
sock.listen(100)
sock.setblocking(False)  # 非阻塞模式

r_list = [sock]
w_list = []
x_list = []
sock_que = {}  # 登记新的socket对象的消息队列

while True:
    r_fds, w_fds, x_fds = select.select(r_list, w_list, x_list)
    for sk_fd in r_fds:
        if sk_fd is sock:  # 判断是否是新的读写套接字
            conn, addr = sk_fd.accept()  # 生成新的读写套接字对象和 客户端地址
            conn.setblocking(False)  # 非阻塞
            print('accepted', conn, 'from', addr)
            r_list.append(conn)
            sock_que[conn] = queue.Queue()  # 在 sock_que 注册新的套接字的消息队列
        else:
            data = sk_fd.recv(1024)
            if data:
                print(f'data:{data}')
                sock_que[sk_fd].put(data)  # socket 读取的消息 存放到 在对应套接字对象的消息队列
                if sk_fd not in w_list:
                    w_list.append(sk_fd)  # 注册该 socket对象到 socket写的列表
            else:
                print('关闭')
                if sk_fd in w_list:
                    w_list.remove(sk_fd)
                if sk_fd in w_fds:
                    w_fds.remove(sk_fd)
                r_list.remove(sk_fd)
                sk_fd.close()

    for sk_w_fd in w_fds:
        # 写套接字
        try:
            next_msg = sock_que[sk_w_fd].get_nowait()
            print(f'回写消息: {next_msg}')
            sk_w_fd.send(next_msg)
        except queue.Empty:
            print('消息为空')
            w_list.remove(sk_w_fd)

    for sk_x_fd in x_fds:
        print('异常套接字')
        r_list.remove(sk_x_fd)
        if sk_x_fd in w_list:
            w_list.remove(sk_x_fd)
        sk_x_fd.close()
        del sock_que[sk_x_fd]

  • 客户端代码
# -*- coding:utf-8 -*-
"""
File Name: socket_client
Author: 82405
Data: 2022/6/2 14:21
-----------------------
Info:

-----------------------
Change Activity:
    2022/6/2: create
"""

import socket
from concurrent.futures import ThreadPoolExecutor

messages = ['hello', 'hello', 'ok', '1+1=2']

svr_addr = ('localhost', 1234)


def echo_client(num):
    """

    :param num:
    :return:
    """
    sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sk.connect(svr_addr)
    for msg in messages:
        sk.send(f'{num}-send:{msg}'.encode('utf8'))
        data = sk.recv(1000)
        print(f'{num}-recv:{data}')
    sk.close()
    print(f'{num} 客户端退出')


if __name__ == '__main__':
    pool = ThreadPoolExecutor(128)
    for i in range(100):
        pool.submit(echo_client, i)
    print('线程执行完毕')
    # echo_client(1)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值