Python网络编程使用select实现socket全双工异步通信功能示例

作者:jiange_zh 时间:2023-04-10 21:06:59 

本文实例讲述了Python网络编程使用select实现socket全双工异步通信功能。分享给大家供大家参考,具体如下:

在前面一篇《Python网络编程之TCP套接字简单用法》中,我们实现了tcp客户端与服务器的通信,但是功能十分局限,发送消息与接收消息不能同时进行。

接下来我将通过select这个模块,来实现全双工通信(随时可以接收信息以及发送信息),当然,用多线程也可以完成,这是后话。

那么,select为何物?

select  -在单线程网络服务中器程序中,管理多个套接字连接

select的原型为(rlist,wlist,xlist[,timeout]),其中rlist是等待读取的对象,wlist是等待写入的对象,xlist是等待异常的对象,最后一个是可选对象,指定等待的时间,单位是s.

select()方法的返回值是准备好的对象的三元组,若在timeout的时间内,没有对象准备好,那么返回值将是空的列表。

它采用的是轮询的方式来实现异步通信的。

在下面程序中,目前主要支持1对1通信,当双方任何一方发送字符串‘88'时,表示结束通信。

下面我们来看看具体实现:

首先是服务器。


#!/usr/bin/python
'test TCP server'
from socket import *
from time import ctime
import select
import sys
HOST = ''
PORT = 21567
BUFSIZ = 1024
ADDR = (HOST, PORT)
tcpSerSock = socket(AF_INET, SOCK_STREAM)
tcpSerSock.bind(ADDR)
tcpSerSock.listen(5)
input = [tcpSerSock, sys.stdin]   #input是一个列表,初始有欢迎套接字以及标准输入
while True:
 print 'waiting for connection...'
 tcpCliSock, addr = tcpSerSock.accept()
 print '...connected from:',addr
 input.append(tcpCliSock)  #将服务套接字加入到input列表中
 while True:
   readyInput,readyOutput,readyException = select.select(input,[],[]) #从input中选择,轮流处理client的请求连接(tcpSerSock),client发送来的消息(tcpCliSock),及服务器端的发送消息(stdin)
   for indata in readyInput:
     if indata==tcpCliSock:  #处理client发送来的消息
       data = tcpCliSock.recv(BUFSIZ)
       print data
       if data=='88':
         input.remove(tcpCliSock)
         break
     else:       #处理服务器端的发送消息
       data = raw_input('>')
       if data=='88':
         tcpCliSock.send('%s' %(data))
         input.remove(tcpCliSock)
         break
       tcpCliSock.send('[%s] %s' %(ctime(), data))
   if data=='88':
     break
 tcpCliSock.close()
tcpSerSock.close()

以下是客户端的代码,非常类似,只是与服务器相比不需要处理请求信息而已。


#!/usr/bin/python
'test tcp client'
from socket import *
from time import ctime
import select
import sys
HOST = 'localhost'
PORT = 21567
BUFSIZ = 1024
ADDR = (HOST, PORT)
tcpCliSock = socket(AF_INET, SOCK_STREAM)
tcpCliSock.connect(ADDR)
input = [tcpCliSock,sys.stdin]
while True:
 readyInput,readyOutput,readyException = select.select(input,[],[])
 for indata in readyInput:
   if indata==tcpCliSock:
     data = tcpCliSock.recv(BUFSIZ)
     print data
     if data=='88':
       break
   else:
     data = raw_input('>')
     if data=='88':
       tcpCliSock.send('%s' %(data))
       break
     tcpCliSock.send('[%s] %s' %(ctime(), data))
 if data=='88':
   break
tcpCliSock.close()

目前为止,已经实现了一对一全双工聊天通信啦。

下面当然要思考下,如何实现多对多通信呢?

我们知道,一个服务器可以为多个客户端服务,即,服务器与客户端本身有着一对多的关系,那么,我们是否可以利用服务器作为中间人,用来传达信息,从而实现多对多通信呢?

举个例子,A想要和B通信,则A将信息发送给服务器,然后再通过服务器转发给B。按照这个思路去写,完成多对多通信应该是可以的,有兴趣的可以尝试一下。

希望本文所述对大家Python程序设计有所帮助。

来源:https://blog.csdn.net/jiange_zh/article/details/47319493

标签:Python,网络编程,select,socket
0
投稿

猜你喜欢

  • 讲解SQL Server2005数据项的分拆与合并

    2009-01-04 14:40:00
  • Go1.18新特性对泛型支持详解

    2024-05-22 17:46:25
  • 使用OpenCV实现仿射变换—平移功能

    2022-11-01 01:45:06
  • 原生JS实现图片轮播 JS实现小广告插件

    2024-04-29 13:55:25
  • PyCharm安装配置Qt Designer+PyUIC图文教程

    2022-10-21 08:44:46
  • Windows下mysql 8.0.29 winx64安装配置方法图文教程

    2024-01-15 14:07:10
  • GO 反射对性能的影响分析

    2024-02-18 06:51:41
  • 微信小程序如何处理token过期问题

    2023-07-02 05:23:54
  • Kears+Opencv实现简单人脸识别

    2022-06-22 05:42:06
  • Python基于opencv的图像压缩算法实例分析

    2022-09-29 11:20:41
  • Python用内置模块来构建REST服务与RPC服务实战

    2023-05-09 19:32:16
  • Golang加权轮询负载均衡的实现

    2024-02-01 04:41:57
  • Selenium执行完毕未关闭chromedriver/geckodriver进程的解决办法(java版+python版)

    2023-03-28 12:39:51
  • JS获取数组最大值、最小值及长度的方法

    2024-04-18 09:29:02
  • Pthon批量处理将pdb文件生成dssp文件

    2021-10-07 13:11:04
  • SQLServer 2000 数据库同步详细步骤[两台服务器]

    2024-01-21 11:18:03
  • 超半数中文网页一年内将“消失”

    2008-03-08 12:49:00
  • opencv实现回形遍历像素算法

    2021-12-26 01:49:30
  • Python实现的ftp服务器功能详解【附源码下载】

    2021-12-23 08:30:55
  • Python 实现数据结构-堆栈和队列的操作方法

    2021-05-25 20:56:16
  • asp之家 网络编程 m.aspxhome.com