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发送邮件接收邮件示例分享
Jan 21 Python
gearman的安装启动及python API使用实例
Jul 08 Python
python映射列表实例分析
Jan 26 Python
Python首次安装后运行报错(0xc000007b)的解决方法
Oct 18 Python
在Python中通过getattr获取对象引用的方法
Jan 21 Python
如何使用Python多线程测试并发漏洞
Dec 18 Python
Pytorch中膨胀卷积的用法详解
Jan 07 Python
使用Django清空数据库并重新生成
Apr 03 Python
解决python图像处理图像赋值后变为白色的问题
Jun 04 Python
Pytorch上下采样函数--interpolate用法
Jul 07 Python
python调用私有属性的方法总结
Jul 24 Python
Python实现简繁体转换
Jun 07 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
Fatal error: Call to undefined function curl_init()解决方法
2010/04/09 PHP
PHP 微信扫码支付源代码(推荐)
2016/11/03 PHP
php异步:在php中使用fsockopen curl实现类似异步处理的功能方法
2016/12/10 PHP
jquery.qrcode在线生成二维码使用示例
2013/08/21 Javascript
jquery 字符串切割函数substring的用法说明
2014/02/11 Javascript
jquery中ready()函数执行的时机和window的load事件比较
2015/06/22 Javascript
浅析JavaScript 箭头函数 generator Date JSON
2016/05/23 Javascript
js微信分享实现代码
2020/10/11 Javascript
关于Vue.nextTick()的正确使用方法浅析
2017/08/25 Javascript
AngularJs ng-change事件/指令的用法小结
2017/11/01 Javascript
在vue项目创建的后初始化首次使用stylus安装方法分享
2018/01/25 Javascript
Vue一次性简洁明了引入所有公共组件的方法
2018/11/28 Javascript
vue项目出现页面空白的解决方案
2019/10/31 Javascript
解决vue admin element noCache设置无效的问题
2019/11/12 Javascript
Vue开发环境跨域访问问题
2020/01/22 Javascript
JavaScript中EventBus实现对象之间通信
2020/10/18 Javascript
Vue 数据响应式相关总结
2021/01/28 Vue.js
详解Python map函数及Python map()函数的用法
2017/11/16 Python
python统计多维数组的行数和列数实例
2018/06/23 Python
Python设计模式之迭代器模式原理与用法实例分析
2019/01/10 Python
完美解决Python matplotlib绘图时汉字显示不正常的问题
2019/01/29 Python
python利用多种方式来统计词频(单词个数)
2019/05/27 Python
机器学习实战之knn算法pandas
2019/06/22 Python
Python中if有多个条件处理方法
2020/02/26 Python
Python3交互式shell ipython3安装及使用详解
2020/07/11 Python
python利用pytesseract 实现本地识别图片文字
2020/12/14 Python
美国杂志订阅折扣与优惠网站:Magazines.com
2016/08/31 全球购物
AE美国鹰日本官方网站: American Eagle Outfitters
2016/12/10 全球购物
德国机车企业:FC-Moto
2017/10/27 全球购物
世界上最大的高分辨率在线图片库:Alamy
2018/07/07 全球购物
Reformation官网:美国女装品牌
2018/09/14 全球购物
JBL美国官方商店:扬声器、耳机等
2019/12/01 全球购物
经贸日语专业个人求职信范文
2013/12/28 职场文书
男方父母证婚词
2014/01/12 职场文书
Python中的np.argmin()和np.argmax()函数用法
2021/06/02 Python
Python办公自动化之教你如何用Python将任意文件转为PDF格式
2021/06/28 Python