Java教程

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

本文主要是介绍单进程、单线程、非堵塞实现并发的验证笔记,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

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

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

这篇关于单进程、单线程、非堵塞实现并发的验证笔记的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!