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

 更新时间:2018年04月12日 14:39:01   作者:惊瑟  
这篇文章主要为大家详细介绍了Python如何实现一个服务器监听多个客户端请求,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

学习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同时连接,服务器输出:

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

客户端A发条消息试试?

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

那另一个呢?

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

再发一条试试?

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

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

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) 

此时再去尝试:

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

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

相关文章

  • Pandas数据类型转换df.astype()及数据类型查看df.dtypes的使用

    Pandas数据类型转换df.astype()及数据类型查看df.dtypes的使用

    Python,numpy都有自己的一套数据格式,本文主要介绍了Pandas数据类型转换df.astype()及数据类型查看df.dtypes的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-07-07
  • python中的异步爬虫详解

    python中的异步爬虫详解

    这篇文章主要介绍了python中的异步爬虫详解,所谓的异步异步 IO,就是发起一个 IO 阻塞的操作,但是不用等到它结束,可以在它执行 IO 的过程中继续做别的事情,当 IO 执行完毕之后会收到它的通知,需要的朋友可以参考下
    2023-08-08
  • Python编译为二进制so可执行文件实例

    Python编译为二进制so可执行文件实例

    今天小编就为大家分享一篇Python编译为二进制so可执行文件实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-12-12
  • python中单双下划线的区别对比分析

    python中单双下划线的区别对比分析

    Python中存在一些特殊的方法,有些方法以双下划线 “__” 开头和结尾,它们是Python的魔法函数,比如__init__()和__str__等等,不用要这种方式命名自己的变量或者函数,这篇文章主要介绍了python里面单双下划线的区别,需要的朋友可以参考下
    2023-04-04
  • 浅谈Python 钉钉报警必备知识系统讲解

    浅谈Python 钉钉报警必备知识系统讲解

    这篇文章主要介绍了浅谈Python 钉钉报警必备知识系统讲解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-08-08
  • 解决pycharm remote deployment 配置的问题

    解决pycharm remote deployment 配置的问题

    今天小编就为大家分享一篇解决pycharm remote deployment 配置的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-06-06
  • 详解Python连接oracle的问题记录与解决

    详解Python连接oracle的问题记录与解决

    这篇文章主要为大家详细介绍了Python连接oracle时会出现的一些问题记录与解决方法,文中的示例代码讲解详细,需要的小伙伴可以参考一下
    2023-04-04
  • Python实现批量生成,重命名和删除word文件

    Python实现批量生成,重命名和删除word文件

    这篇文章主要为大家详细介绍了Python如何利用第三方库实现批量生成、重命名和删除word文件的功能,文中的示例代码讲解详细,需要的可以参考一下
    2023-03-03
  • python八大排序算法速度实例对比

    python八大排序算法速度实例对比

    这篇文章主要介绍了Python八大排序算法速度实例对比,具有一定参考价值,需要的朋友可以参考下。
    2017-12-12
  • python中round函数如何使用

    python中round函数如何使用

    在本篇文章里小编给大家整理了关于python的round函数用法总结内容,需要的朋友们可以学习下。
    2020-06-06

最新评论