Python实现一个服务器监听多个客户端请求


Posted in Python onApril 12, 2018

学习Python网络通信的时候发现书上只有一个服务端对应一个客户端的情形,于是自己想自己动手实现一个服务端响应多个客户端。

首先建立服务器的socket来监听客户端的请求:

tcpSerSock=socket(AF_INET,SOCK_STREAM) 
tcpSerSock.bind(ADDR) 
tcpSerSock.listen(5)

这样服务器的监听socket就建好了。

接下来的思路是,如果要监听多个客户端,则

tcpSerSock.accept() #(accept()是阻塞式的)

必须放进一个while循环(不放进循环监听一次就没了)。然而,这里就有问题了。如果按照一对一的那种处理顺序,客户端A连进来后,程序顺序向下执行,服务端要再写一个while循环,用来处理客户端A的请求,如果此时客户端B再来请求,服务器将接收不到。于是,很自然想到,将监听和处理放到不同的线程进行处理。我选择将监听放入主线程,将处理放进子线程。该服务器功能为接收到客户端的数据加上时间戳后返回给客户端。服务端完整代码如下:

#coding=utf-8 
#!/usr/bin/env python 
''''' 
author:Mr.Jing 
created on Fri Sep 22 14:29:03 2017 
platfrom:win10,python2.7 
''' 
 
from socket import * 
from time import ctime 
import threading 
import time 
HOST='' 
PORT=2159 
BUFSIZ=1024 
ADDR = (HOST,PORT) 
 
tcpSerSock=socket(AF_INET,SOCK_STREAM) 
tcpSerSock.bind(ADDR) 
tcpSerSock.listen(5) 
socks=[]        #放每个客户端的socket 
 
def handle(): 
 while True: 
  for s in socks: 
   data = s.recv(BUFSIZ) 
   if not data: 
    socks.remove(s) 
    continue 
   s.send('[%s],%s' % (ctime(), data)) #加上时间戳返回 
 
t = threading.Thread(target=handle)    #子线程 
if __name__ == '__main__': 
 t.start() 
 print u'我在%s线程中 ' % threading.current_thread().name #本身是主线程 
 print 'waiting for connecting...' 
 while True: 
  clientSock,addr = tcpSerSock.accept() 
  print 'connected from:', addr 
  socks.append(clientSock)

两个客户端A和B同时连接,服务器输出:

Python实现一个服务器监听多个客户端请求

可以看到服务端是可以相应多个客户端的。

客户端A发条消息试试?

Python实现一个服务器监听多个客户端请求

服务器返回来了带时间戳的消息,goodjob。

那另一个呢?

Python实现一个服务器监听多个客户端请求

很棒。服务器都能做出响应。

再发一条试试?

Python实现一个服务器监听多个客户端请求

发现服务器没响应了,这是怎么回事呢?

经过仔细勘察发现是因为这句:

data = s.recv(BUFSIZ)

因为recv方法是阻塞的,也就是说,当轮训到某个客户端,比如A,这句等待A发消息,不发消息就不往下走,所以此时B再去发消息的话服务器就收不到了。

那该怎么办呢?

很容易想到,将其设为非阻塞就好了。但上网找了好久,虽然找到可以用setblocking(0)  将套接字设为非阻塞,然而具体怎么用却很少有人讲清楚。查资料后终于搞明白,非阻塞的recv方法会继续向下执行,若超时得不到数据则会抛出异常。

修改后的代码如下:

#coding=utf-8 
#!/usr/bin/env python 
''''' 
author:Mr.Jing 
created on Fri Sep 22 14:29:03 2017 
platfrom:win10,python2.7 
''' 
 
from socket import * 
from time import ctime 
import threading 
import time 
HOST='' 
PORT=2159 
BUFSIZ=1024 
ADDR = (HOST,PORT) 
 
tcpSerSock=socket(AF_INET,SOCK_STREAM) 
tcpSerSock.bind(ADDR) 
tcpSerSock.listen(5) 
socks=[]        #放每个客户端的socket 
 
def handle(): 
 while True: 
  for s in socks: 
   try: 
    data = s.recv(BUFSIZ)  #到这里程序继续向下执行 
   except Exception, e:   
    continue 
   if not data: 
    socks.remove(s) 
    continue 
   s.send('[%s],%s' % (ctime(), data)) 
 
t = threading.Thread(target=handle)    #子线程 
if __name__ == '__main__': 
 t.start() 
 print u'我在%s线程中 ' % threading.current_thread().name #本身是主线程 
 print 'waiting for connecting...' 
 while True: 
  clientSock,addr = tcpSerSock.accept() 
  print 'connected from:', addr 
  clientSock.setblocking(0) 
  socks.append(clientSock)

此时再去尝试:

Python实现一个服务器监听多个客户端请求

客户端随便输都会得到响应。任务达成!

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python实现猜数字游戏(无重复数字)示例分享
Mar 29 Python
Python中除法使用的注意事项
Aug 21 Python
python实现封装得到virustotal扫描结果
Oct 05 Python
Python中的Numpy矩阵操作
Aug 12 Python
Python判断是否json是否包含一个key的方法
Dec 31 Python
Python3.5 Pandas模块之Series用法实例分析
Apr 23 Python
Python多线程及其基本使用方法实例分析
Oct 29 Python
Python代码生成视频的缩略图的实例讲解
Dec 22 Python
python zip,lambda,map函数代码实例
Apr 04 Python
python 如何将office文件转换为PDF
Sep 22 Python
python实现图像随机裁剪的示例代码
Dec 10 Python
python包的导入方式总结
Mar 02 Python
python使用socket创建tcp服务器和客户端
Apr 12 #Python
Python简单实现两个任意字符串乘积的方法示例
Apr 12 #Python
Java与Python两大幸存者谁更胜一筹呢
Apr 12 #Python
python打包压缩、读取指定目录下的指定类型文件
Apr 12 #Python
pandas全表查询定位某个值所在行列的方法
Apr 12 #Python
Python Pandas找到缺失值的位置方法
Apr 12 #Python
Pandas 数据框增、删、改、查、去重、抽样基本操作方法
Apr 12 #Python
You might like
实例讲解yii2.0在php命令行中运行的步骤
2015/12/01 PHP
PHP输出Excel PHPExcel的方法
2018/07/26 PHP
图像替换新技术 状态域方法
2010/01/28 Javascript
使用jquery动态加载js文件的方法
2014/12/24 Javascript
js读取并解析JSON类型数据的方法
2015/11/14 Javascript
javascript下拉列表中显示树形菜单的实现方法
2015/11/17 Javascript
js 求时间差的实现代码
2016/04/26 Javascript
学习Javascript闭包(Closure)知识
2016/08/07 Javascript
AngularJS  ng-table插件设置排序
2016/09/21 Javascript
详解MVC如何使用开源分页插件(shenniu.pager.js)
2016/12/16 Javascript
使用原生js写ajax实例(推荐)
2017/05/31 Javascript
ReactNative实现图片上传功能的示例代码
2017/07/11 Javascript
Windows下使用Nodejs运行js的方法
2017/09/02 NodeJs
[原创]jquery判断元素内容是否为空的方法
2018/05/04 jQuery
vue-cli 为项目设置别名的方法
2019/10/15 Javascript
jquery实现烟花效果(面向对象)
2020/03/10 jQuery
Python 中的 else详解
2016/04/23 Python
python3.6连接MySQL和表的创建与删除实例代码
2017/12/28 Python
浅谈Pycharm中的Python Console与Terminal
2019/01/17 Python
python自动点赞功能的实现思路
2020/02/26 Python
python爬虫beautifulsoup解析html方法
2020/12/07 Python
美国在线奢侈品寄售商店:Luxury Garage Sale
2018/08/19 全球购物
为您搜罗全球潮流時尚品牌:HBX
2019/12/04 全球购物
物业保安主管岗位职责
2013/12/25 职场文书
运动会开幕式邀请函
2014/01/22 职场文书
研修第一天随笔感言
2014/02/15 职场文书
希特勒的演讲稿
2014/05/23 职场文书
观看《周恩来的四个昼夜》思想汇报
2014/09/12 职场文书
2014小学数学教师个人工作总结
2014/12/18 职场文书
2015年新农合工作总结
2015/03/30 职场文书
企业培训简报范文
2015/07/20 职场文书
Python生成九宫格图片的示例代码
2021/04/14 Python
MySQL性能压力基准测试工具sysbench的使用简介
2021/04/21 MySQL
详解Python中的进程和线程
2021/06/23 Python
世界十大儿童漫画书排名,法国国宝漫画排第五,第二是轰动日本连环
2022/03/18 欧美动漫
Redis基本数据类型List常用操作命令
2022/06/01 Redis