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和MD5实现网站挂马检测程序
Mar 13 Python
Python常用模块用法分析
Sep 08 Python
编写Python爬虫抓取豆瓣电影TOP100及用户头像的方法
Jan 20 Python
Python学习pygal绘制线图代码分享
Dec 09 Python
利用Python复制文件的9种方法总结
Sep 02 Python
python基于event实现线程间通信控制
Jan 13 Python
屏蔽Django admin界面添加按钮的操作
Mar 11 Python
python中的socket实现ftp客户端和服务器收发文件及md5加密文件
Apr 01 Python
使用python无账号无限制获取企查查信息的实例代码
Apr 17 Python
python使用多线程查询数据库的实现示例
Aug 17 Python
python遍历路径破解表单的示例
Nov 21 Python
Python 匹配文本并在其上一行追加文本
May 11 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
Ajax+PHP 边学边练之四 表单
2009/11/27 PHP
ThinkPHP5.0框架控制器继承基类和自定义类示例
2018/05/25 PHP
jscript之List Excel Color Values
2007/06/13 Javascript
javascript实现的动态文字变换
2007/07/28 Javascript
有一段有意思的代码-javascript现实多行信息
2007/08/26 Javascript
JavaScript中的console.trace()函数介绍
2014/12/29 Javascript
Javascript从数组中随机取出不同元素的两种方法
2016/09/22 Javascript
使用JS正则表达式 替换括号,尖括号等
2016/11/29 Javascript
jquery+ajax实现省市区三级联动 (封装和不封装两种方式)
2017/05/15 jQuery
微信小程序实现点击按钮修改view标签背景颜色功能示例【附demo源码下载】
2017/12/06 Javascript
详解angular部署到iis出现404解决方案
2018/08/14 Javascript
深入理解与使用keep-alive(配合router-view缓存整个路由页面)
2018/09/25 Javascript
[01:50]2014DOTA2西雅图邀请赛 专访欢乐周宝龙
2014/07/08 DOTA
[02:55]2018DOTA2国际邀请赛勇士令状不朽珍藏Ⅲ饰品一览
2018/08/01 DOTA
python创建只读属性对象的方法(ReadOnlyObject)
2013/02/10 Python
Python随机生成数模块random使用实例
2015/04/13 Python
Python中用于检查英文字母大写的isupper()方法
2015/05/19 Python
windows 10下安装搭建django1.10.3和Apache2.4的方法
2017/04/05 Python
Python对字符串实现去重操作的方法示例
2017/08/11 Python
python pandas 对series和dataframe的重置索引reindex方法
2018/06/07 Python
Python实现简单的用户交互方法详解
2018/09/25 Python
django多文件上传,form提交,多对多外键保存的实例
2019/08/06 Python
百思买美国官网:Best Buy
2016/07/28 全球购物
Jones New York官网:美国女装品牌,受白领女性欢迎
2019/11/26 全球购物
Yankee Candle官网:美国最畅销蜡烛品牌之一
2020/01/05 全球购物
捷克购买家具网站:JENA nábytek
2020/03/19 全球购物
大专学生推荐信范文
2013/11/19 职场文书
办公室文员自荐书
2014/02/03 职场文书
财务会计实训报告
2014/11/05 职场文书
拯救大兵瑞恩观后感
2015/06/09 职场文书
校园安全教育心得体会
2016/01/15 职场文书
《我和小伙伴》教学反思
2016/02/20 职场文书
简述python四种分词工具,盘点哪个更好用?
2021/04/13 Python
使用Python+OpenCV进行卡类型及16位卡号数字的OCR功能
2021/08/30 Python
Android自定义scrollview实现回弹效果
2022/04/01 Java/Android
SqlServer常用函数及时间处理小结
2023/05/08 SQL Server