1, 必须在非阻塞模式下,才能实现IO的多路复用,否则一个卡住就都卡住了。(单线程下的多路复用)

先检测自己,现在没有客户端连进来,所以会卡住。

# 用select去模拟socket,实现单线程下的多路复用
import select
import socket
import queue server = socket.socket()
server.bind(('localhost', 9000))
server.listen(1024)
server.setblocking(False) # 设置为不阻塞,accept/recv没有数据都不阻塞,只会报错。 inputs = [server, ] # 先检测自己,如果我有活动了,说明有客户端要连我了。
outputs = []
select.select(inputs, outputs, inputs) # 第一个参数:需要检测哪些链接就放进来。操作系统发现100个里面有1个在活动,就会返回这100个。 # 第二个参数: # 第三个参数:让操作系统检测100个的哪个有问题,就把有问题的返回。还是把100个放到这里。 server.accept() #没有链接也不阻塞,只是返回一个错误。

运行结果:

C:\abccdxddd\Oldboy\python-3.5.2-embed-amd64\python.exe C:/abccdxddd/Oldboy/Py_Exercise/Day10/ex3_Client.py

2. 客户端代码:

import socket
HOST = 'localhost' # The remote host
PORT = 9000 # The same port as used by the server s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT)) while True:
msg = bytes(input(">>:"), encoding="utf8")
s.sendall(msg)
data = s.recv(1024)
# print(data)
print('Received', repr(data)) #repr:格式化输出 s.close()

服务器端:

# 用select去模拟socket,实现单线程下的多路复用
import select
import socket
import queue server = socket.socket()
server.bind(('localhost', 9000))
server.listen(1024)
server.setblocking(False) # 设置为不阻塞,accept/recv没有数据都不阻塞,只会报错。 inputs = [server, ] # 先检测自己,如果我有活动了,说明有客户端要连我了。
outputs = []
readable,writeable,exceptional=select.select(inputs, outputs, inputs) # 第一个参数:需要检测哪些链接就放进来。操作系统发现100个里面有1个在活动,就会返回这100个。 # 第二个参数: # 第三个参数:让操作系统检测100个的哪个有问题,就把有问题的返回。还是把100个放到这里。 print(readable,writeable,exceptional) #新来的链接会出现在readable里面, server.accept() #没有链接也不阻塞,只是返回一个错误。

运行结果:fd=240 文件描述符

C:\abccdxddd\Oldboy\python-3.5.2-embed-amd64\python.exe C:/abccdxddd/Oldboy/Py_Exercise/Day10/ex3_Client.py
[<socket.socket fd=240, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9000)>] [] [] Process finished with exit code 0

3.

# 用select去模拟socket,实现单线程下的多路复用
import select
import socket
import queue server = socket.socket()
server.bind(('localhost', 9000))
server.listen(1024)
server.setblocking(False) # 设置为不阻塞,accept/recv没有数据都不阻塞,只会报错。 inputs = [server, ] # 先检测自己,如果我有活动了,说明有客户端要连我了。
outputs = []
readable,writeable,exceptional=select.select(inputs, outputs, inputs) # 第一个参数:需要检测哪些链接就放进来。操作系统发现100个里面有1个在活动,就会返回这100个。 # 第二个参数: # 第三个参数:让操作系统检测100个的哪个有问题,就把有问题的返回。还是把100个放到这里。 print(readable,writeable,exceptional) #新来的链接会出现在readable里面, for r in readable:
conn,addr=server.accept() #没有链接也不阻塞,只是返回一个错误。
print(conn,addr)

客户端:

import socket
HOST = 'localhost' # The remote host
PORT = 9000 # The same port as used by the server s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT)) while True:
msg = bytes(input(">>:"), encoding="utf8")
s.sendall(msg)
data = s.recv(1024)
# print(data)
print('Received', repr(data)) #repr:格式化输出 s.close()

运行结果:

C:\abccdxddd\Oldboy\python-3.5.2-embed-amd64\python.exe C:\abccdxddd\Oldboy\Py_Exercise\Day10\select_socket_server2.py
[<socket.socket fd=240, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9000)>] [] []
<socket.socket fd=336, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9000), raddr=('127.0.0.1', 49587)> ('127.0.0.1', 49587) Process finished with exit code 0

至此链接已经建立。

4.最终版本

服务器端:

import select,socket
server=socket.socket()
server.bind(('localhost',9000))
server.listen(1024) #最多可以监听1024个
server.setblocking(False)
inputs=[server,]
outputs=[]
while True:
readable,writeable,exceptional=select.select(inputs,outputs,inputs) #select帮着去检测这100个链接
print(readable,writeable,exceptional)
for r in readable:
if r is server:
conn,addr=server.accept()
print('来了个新链接',addr)
inputs.append(conn)
else:
data=r.recv(1024)
print('收到数据',data)
r.send(data)

客户端:

import socket
s=socket.socket()
s.connect(('localhost',9000))
while True:
msg=bytes(input(">>:"),encoding='utf8')
s.sendall(msg)
data=s.recv(1024)
print('Received',repr(data))
s.close()

运行结果:

C:\abccdxddd\Oldboy\python-3.5.2-embed-amd64\python.exe C:/abccdxddd/Oldboy/Py_Exercise/Day10/select_socket_server2.py
[<socket.socket fd=232, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9000)>] [] []
来了个新链接 ('127.0.0.1', 61118)
[<socket.socket fd=324, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9000), raddr=('127.0.0.1', 61118)>] [] []
收到数据 b'1'
[<socket.socket fd=324, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9000), raddr=('127.0.0.1', 61118)>] [] []
收到数据 b'2'
[<socket.socket fd=232, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9000)>] [] []
来了个新链接 ('127.0.0.1', 61119)
[<socket.socket fd=328, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9000), raddr=('127.0.0.1', 61119)>] [] []
收到数据 b'3'
[<socket.socket fd=328, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9000), raddr=('127.0.0.1', 61119)>] [] []
收到数据 b'4'
[<socket.socket fd=324, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9000), raddr=('127.0.0.1', 61118)>] [] []
收到数据 b'7'
[<socket.socket fd=328, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9000), raddr=('127.0.0.1', 61119)>] [] []
收到数据 b'8'

一个server端,两个client端

用select模拟一个socket server的更多相关文章

  1. 用select模拟一个socket server成型版2

    1.字典队列测试 import queue msg_dic={} msg_dic[1]=queue.Queue() msg_dic[1].put('hello') msg_dic[1].put('bo ...

  2. 用select模拟一个socket server成型版

    1.你往output里面放什么,下次循环就出什么.  2. 1.服务器端:实现了收和发的分开进行 import select,socket,queue server=socket.socket() s ...

  3. 用select (多路复用)模拟一个 socket server

    需求:用select (多路复用)模拟一个 socket server.可以接收多并发. 1. 一开始是检测自己,如果我有活动了,就说明有客户端要连我了. #用select去模拟socket,实现单线 ...

  4. python利用select实现的Socket Server

    # 利用python的select模块实现简单的Socket Sever #实现多用户访问,再次基础上可以实现FTP Server应用程序 # 发布目的,在于解决了客户端强行终止时,服务器端也跟着程序 ...

  5. C语言写了一个socket server端,适合windows和linux,用GCC编译运行通过

    ////////////////////////////////////////////////////////////////////////////////* gcc -Wall -o s1 s1 ...

  6. VFP 用 SPT 来发布一条 SELECT 到一个新的 SQL Server 表

    为了发布一条 SQL SELECT 语句来创建一个新的 SQL Server 表,  SQL Server 数据库的 select into/bulkcopy 选项必须是可用的. 在默认情况下, 对于 ...

  7. 面向连接的Socket Server的简单实现(简明易懂)

    一.基本原理 有时候我们需要实现一个公共的模块,需要对多个其他的模块提供服务,最常用的方式就是实现一个Socket Server,接受客户的请求,并返回给客户结果. 这经常涉及到如果管理多个连接及如何 ...

  8. C#中自己动手创建一个Web Server(非Socket实现)

    目录 介绍 Web Server在Web架构系统中的作用 Web Server与Web网站程序的交互 HTTPListener与Socket两种方式的差异 附带Demo源码概述 Demo效果截图 总结 ...

  9. [Golang] 从零開始写Socket Server(3): 对长、短连接的处理策略(模拟心跳)

    通过前两章,我们成功是写出了一套凑合能用的Server和Client,并在二者之间实现了通过协议交流.这么一来,一个简易的socket通讯框架已经初具雏形了,那么我们接下来做的.就是想办法让这个框架更 ...

随机推荐

  1. [ES]Elasticsearch在windows下的安装

    1.环境 win7 64位 2.下载包环境 https://www.elastic.co/cn/downloads/elasticsearch 选择对应安装包 3.安装过程 解压安装包,例如我的,解压 ...

  2. 如何实现最佳的跨平台游戏体验?Unity成亮解密实时渲染

    7月31日,2018云创大会游戏论坛在杭州国际博览中心103B圆满举行.本场游戏论坛聚焦探讨了可能对游戏行业发展有重大推动的新技术.新实践,如AR.区块链.安全.大数据等. Unity大中华区技术经理 ...

  3. 机器学习的5种“兵法"

    大数据文摘作品,欢迎个人转发朋友圈,自媒体.媒体.机构转载务必申请授权,后台留言“机构名称+转载”,申请过授权的不必再次申请,只要按约定转载即可. 作者:Jason Brownlee 译者:Clair ...

  4. tomcat6升级到7时400问题,以及url带有汉字时出错。

    tomcat6升级到7时400问题: 在文件catalina.properties后加入tomcat.util.http.parser.HttpParser.requestTargetAllow=|. ...

  5. 初学Direct X(4)

    初学Direct X(4) 本文学着做出一个如下的小游戏 游戏方式是使用键盘控制红色的Bucket收集蓝色的炸弹 1.酝酿一下 现在我已经掌握: 将位图文件加载到内存 绘制位图到buckbuffer ...

  6. Spring Cloud(五):Hystrix 监控面板【Finchley 版】

    Spring Cloud(五):Hystrix 监控面板[Finchley 版]  发表于 2018-04-16 |  更新于 2018-05-10 |  在上一篇 Hystrix 的介绍中,我们提到 ...

  7. python常用命令—查看模块所在位置

    环境:ipython3 交互式解释器 语法: import 模块名 模块名.__file__ 功能: 查看模块的所在位置 例:

  8. 【Linux】Face Recognition的封装

    使用虹软的人脸识别 写了一个linux下的Face Recognition的封装,当作是练习. C++的封装,结合opencv,使用方便.https://github.com/zacario-li/F ...

  9. js经典试题之数据类型

    js经典试题之数据类型 1:输出"B" + "a" + + "B" + "a"的值: 答案:BaNaNa. 分析:因为+ ...

  10. 微信小程序学习:开发注意点

    11月2日更新: 微信小程序支持内嵌网页,新增 <web-view /> 组件调试支持: 传送门 <!-- wxml --> <!-- 指向微信公众平台首页的web-vi ...