单进程、单线程、非堵塞实现并发的验证笔记

该博客讨论了如何使用Python实现单进程、单线程的非阻塞I/O来并发处理客户端连接。通过设置套接字为非阻塞,并利用异常处理来检测新客户端,将连接的客户端添加到列表中。当接收到空数据时,表明客户端已断开,此时从列表中移除该客户端,避免资源浪费。这种方法有效地实现了对多个客户端的并发管理。
摘要由CSDN通过智能技术生成

这一章节是对上一章节的验证。上一章节讲到了单进程、单线程非堵塞实现并发的原理。主要关键点就是设置非堵塞和定义一个空列表。向列表里面添加客户端。但是这个地方有一个严重的问题,就是客户端添加到列表之后,后面每一次遍历都会将列表里面的客户端全部都遍历一遍,即使这个客户端已经断开连接了,这样会耗费大量资源和精力。那么此时将断开的客户端从列表里面删除掉就是关键点了。此时只需要添加一个判断即可。
因为当关闭客户端的时候,客户端发送的数据为空,此时只要判断服务器接收到客户端发送的数据为空的时候,删除掉列表里面的客户端即可。具体的代码实现如下:

import socket
import time


tcp_socket_tcp = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcp_socket_tcp.bind(("", 7780))
tcp_socket_tcp.listen(128)
tcp_socket_tcp.setblocking(False)

client_socket_list = list()

while True:
    time.sleep(3)
    try:
        new_socket, new_addr = tcp_socket_tcp.accept()
        # 等待客户端的到来,只要没有客户端连接,这个地方就会堵塞。因为设置了非堵塞,accept
        # 返回值为空。那么这个地方会就产生异常。只要产生异常,则说明这个地方就还没有新的客户端连接
        # 只要没有产生异常,则accept就有返回值,说明有新的客户端连接。
    except Exception as ret:
        print("...没有新的客户端到来...")
    else:
        print("...只要没有产生异常,那么意味着,来了一个新的客户端...")
        # 产生的新的套接字new_socket,一旦调用recv的时候,立马就会堵塞。那么此时也应该将新的套接字new_socket
        # 设置为非堵塞。那么一旦调用recv,如果没有数据到来,就会产生异常。反过来,只要不产生异常,就说明客户端
        # 发送过来了数据了。
        new_socket.setblocking(False)  # 设置套接字为非堵塞

        client_socket_list.append(new_socket)
        # 新产生的套接字是接收客户端是否产生数据,因此这个套接字的接收信息循环程序不能放在里面。
        # 因为一旦监听套接字没有新的客户端到来,就会产生异常,只要主程序产生异常,新产生的套接字就
        # 不会运行,此时必挂。那么此时可以在外面定义一个空列表。将新的套接字添加到列表中,然后
        # for循环遍历列表。只要new_socket 在列表中,则就会一直循环接收数据。
        # 如果产生新的套接字,列表中就会有两个套接字,则遍历列表中两个套接字是否产生数据。这样就实现了
        # 单进程、单线程检测多个套接字,也就实现了单进程和单线程实现http服务器。
    for client_socket in client_socket_list:
        try:
            recv_data = client_socket.recv(1024)
        except Exception as ret:
            print("...这个客户端没有发送过来数据...")
        else:
            print("...没有异常...")
            if recv_data:
                # 只要接收到了数据,那么就可以进行其他的一些操作了。
                print("...客户端发送过来了数据...")
                print(recv_data)
                # 对方调用了close导致recv返回
            else:
            	# 客户端发送的数据为空,此时删除列表里面关闭的客户端。
                client_socket.close()
                client_socket_list.remove(client_socket)
                print("...客户端关闭...")

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

维维不威威

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值