伍佰目录 短网址
  当前位置:海洋目录网 » 站长资讯 » 站长资讯 » 文章详细 订阅RssFeed

【py3】使用单线程服务多个客户端请求

来源:本站原创 浏览:65次 时间:2022-12-03

网络交互离不开socket,浏览器访问数据是请求-应答模式,服务器收到数据后会根据请求地址解析并返回对应文件内容(io)。本文以tcp为例,使用python3模拟服务端,使用浏览器作为客户端,来实现一个线程为多个浏览器客户端服务的示例。

先来看下通常的服务端启动程序,服务端根据host和port创建套接字,注意这里要调用listen方法开始监听,然后才能accept接收客户端连接。

(hostport):    server = socket.socket(socket.AF_INETsocket.SOCK_STREAM)    server.bind((hostport))    server.listen()    server

传统的做法是服务端socket在无限循环中accept,然而accept方法默认是阻塞的,会阻塞在那里直到有客户端来连接,所以单线程时无法为多个客户端同时服务。

:    clientaddr = server.accept()

如果能解阻塞,那么线程自然可以继续向下执行提供服务,我们可以将服务端socket设置为非阻塞。注意这里要捕获异常,防止没有客户端连接到来导致程序异常退出。

server.setblocking(False)
:    :        clientaddr = server.accept()    :        :        (% addr)

以上我们就解决了accept阻塞的问题,接下来就可以根据客户端socket进行相应的读写处理了。使用recv方法进行数据读取,这里简单设置为每次读取1024字节。

data = client.recv(1024)

因为客户端socket默认也是阻塞的,所以recv方法会阻塞等待数据到来,所以想要线程继续向下执行,我们要解决recv阻塞问题。同服务端socket设置,将客户端socket设置为非阻塞。

server.setblocking(False)
:    :        clientaddr = server.accept()    :        :        (% addr)        client.setblocking()    :        data = client.recv()    :        :        data:            (% ((addr)data.decode()))        :            client.close()

以上我们就实现了客户端非阻塞,这样客户端socket接收数据也变成非阻塞的了,注意同样需要捕获异常,防止程序异常退出。现在可以接收多个客户端请求了,但是无法为客户端服务,因为服务端只接受了客户端数据,还没有做出响应。先来实现一个响应客户端的方法。

(client):    response = response += response += response += % random.randint()    client.send(response.encode())    client.close()

响应有了,依然要考虑新的问题,服务端也不知道服务哪个client,所以我们需要找一个地方把连接进来的客户端socket保存起来然后循环迭代处理。最终整理如下,把阻塞的地方消灭掉,使得线程可以继续向下执行,完成一个进程下一个线程为多个客户端服务。

randomsocket(hostport):    server.setblocking()    serverclients = ()():    server = bind()    :        :            clientaddr = server.accept()        :            :            (% addr)            client.setblocking()            clients.append(client)        cli clients:            :                data = cli.recv()            :                :                data:                    (% ((addr)data.decode()))                    send(cli)                :                    clients.remove(cli)                    cli.close()__name__ == :    main()

下面我们使用浏览器访问一下,http://127.0.0.1:8000,效果如下:


  推荐站点

  • At-lib分类目录At-lib分类目录

    At-lib网站分类目录汇集全国所有高质量网站,是中国权威的中文网站分类目录,给站长提供免费网址目录提交收录和推荐最新最全的优秀网站大全是名站导航之家

    www.at-lib.cn
  • 中国链接目录中国链接目录

    中国链接目录简称链接目录,是收录优秀网站和淘宝网店的网站分类目录,为您提供优质的网址导航服务,也是网店进行收录推广,站长免费推广网站、加快百度收录、增加友情链接和网站外链的平台。

    www.cnlink.org
  • 35目录网35目录网

    35目录免费收录各类优秀网站,全力打造互动式网站目录,提供网站分类目录检索,关键字搜索功能。欢迎您向35目录推荐、提交优秀网站。

    www.35mulu.com
  • 就要爱网站目录就要爱网站目录

    就要爱网站目录,按主题和类别列出网站。所有提交的网站都经过人工审查,确保质量和无垃圾邮件的结果。

    www.912219.com
  • 伍佰目录伍佰目录

    伍佰网站目录免费收录各类优秀网站,全力打造互动式网站目录,提供网站分类目录检索,关键字搜索功能。欢迎您向伍佰目录推荐、提交优秀网站。

    www.wbwb.net