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 23 Python
python使用wxpython开发简单记事本的方法
May 20 Python
Django中对数据查询结果进行排序的方法
Jul 17 Python
python中文编码与json中文输出问题详解
Aug 24 Python
python 解决动态的定义变量名,并给其赋值的方法(大数据处理)
Nov 10 Python
python2.7实现复制大量文件及文件夹资料
Aug 31 Python
利用python计算时间差(返回天数)
Sep 07 Python
Python Sphinx使用实例及问题解决
Jan 17 Python
python爬虫开发之Request模块从安装到详细使用方法与实例全解
Mar 09 Python
django美化后台django-suit的安装配置操作
Jul 12 Python
Python pickle模块常用方法代码实例
Oct 10 Python
Python 游戏大作炫酷机甲闯关游戏爆肝数千行代码实现案例进阶
Oct 16 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
图书管理程序(三)
2006/10/09 PHP
利用PHP脚本在Linux下用md5函数加密字符串的方法
2015/06/29 PHP
PHP实现简单汉字验证码
2015/07/28 PHP
Symfony2函数用法实例分析
2016/03/18 PHP
PHP图像处理技术实例总结【绘图、水印、验证码、图像压缩】
2018/12/08 PHP
Javascript的构造函数和constructor属性
2010/01/09 Javascript
JavaScript和JQuery实用代码片段(一)
2010/04/07 Javascript
javascript实现跳转菜单的具体方法
2013/07/05 Javascript
jquery获取URL中参数解决中文乱码问题的两种方法
2013/12/18 Javascript
jQuery focus和blur事件的应用详解
2014/01/26 Javascript
AngularJS 最常用的功能汇总
2016/02/17 Javascript
js简单判断移动端系统的方法
2016/02/25 Javascript
AngularJS用户选择器指令实例分析
2016/11/04 Javascript
jQuery实现表格与ckeckbox的全选与单选功能
2016/11/24 Javascript
js 作用域和变量详解
2017/02/16 Javascript
nodejs+express实现文件上传下载管理网站
2017/03/15 NodeJs
js图片轮播插件的封装
2017/07/21 Javascript
详解基于DllPlugin和DllReferencePlugin的webpack构建优化
2018/06/28 Javascript
jQuery超简单遮罩层实现方法示例
2018/09/06 jQuery
VUE基于NUXT的SSR 服务端渲染
2018/11/30 Javascript
如何使用electron-builder及electron-updater给项目配置自动更新
2018/12/24 Javascript
vue+element实现表单校验功能
2019/05/20 Javascript
小程序如何使用分包加载的实现方法
2019/05/22 Javascript
Python多进程multiprocessing用法实例分析
2017/08/18 Python
python实现可变变量名方法详解
2019/07/01 Python
在tensorflow中实现屏蔽输出的log信息
2020/02/04 Python
Python如何基于Tesseract实现识别文字功能
2020/06/05 Python
Html5实现用户注册自动校验功能实例代码
2016/05/24 HTML / CSS
美国南加州的原创极限运动潮牌:Vans(范斯)
2016/08/05 全球购物
Urban Outfitters美国官网:美国生活方式品牌
2016/08/26 全球购物
微软英国官方网站:Microsoft英国
2016/10/15 全球购物
联想韩国官网:Lenovo Korea
2018/05/10 全球购物
客户经理竞聘演讲稿
2014/05/15 职场文书
旅游与酒店管理专业求职信
2014/07/21 职场文书
作文批改评语
2014/12/25 职场文书
关于销售人员的年终工作总结要点
2019/08/15 职场文书