ICode9

精准搜索请尝试: 精确搜索
首页 > 系统相关> 文章详细

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

2021-09-07 22:57:48  阅读:123  来源: 互联网

标签:... socket 单线程 笔记 列表 并发 tcp 接字 客户端


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

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("...客户端关闭...")

标签:...,socket,单线程,笔记,列表,并发,tcp,接字,客户端
来源: https://blog.csdn.net/m0_56880799/article/details/120169134

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有