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. 引领技术变革,腾讯云、腾讯WeTest和英特尔,合作布局云游戏

    WeTest 导读 ChinaJoy作为中国泛娱乐产业年度风向标,受到全球业界的高度关注.在本届ChinaJoy上,腾讯云.腾讯WeTest和英特尔,合作为游戏玩家.游戏开发者等业界人士联合展出了云游 ...

  2. JDK11安装后,环境变量的坑

    安装了最新的JDK11,安装完后设置环境变量,打开CMD,没生效 检查了3遍,都没发现问题,在PATH中将JAVA设置移到第一也不行 最后偶然发现,在点击如图右下的‘编辑文本’,用文本方式编辑时,发现 ...

  3. Linux命令应用大词典-第3章 文本编辑器

    3.1 vi:文本编辑器 3.2 nano:编辑器 3.3 view:文办编辑器 3.4 ex:文本编辑器 3.5 ed:文本编辑器 3.6 red:文本编辑器 3.1 vi:文本编辑器 1.对文本创 ...

  4. jdk从1.8换成1.7后,查看版本还是1.8解决方法

    因学习需要,需将jdk从1.8更改到1.7,其中遇到了些小麻烦,如果你也遇到这种麻烦,可以借鉴一下我的解决方法. 1.jdk的安装及环境变量的配置,详见https://jingyan.baidu.co ...

  5. 题解 CF682C 【Alyona and the Tree】

    简单搜索题,我们每找到一组不满足题目给出条件的点和边就将其整个子树删除,然后最终答案加上该子树的大小即可.注意,搜索的时候如果当前的边权和sum已经为负了,应该将其改为0(可以想想为什么) 注:题目翻 ...

  6. cronolog:日志分割工具

    一. 引言 因为tomcat的catalina.out日志无法按照日期自动创建,因此采用cronnlog分割. 二. 安装与配置 1.安装cronolog: yum install -y cronol ...

  7. Centos7下安装mysql服务

    yum install -y perl-Module-Install.noarch yum -y install perl perl-devel #命令下载mysql wget http://dev. ...

  8. FPGA学习-PS2接口

    选自http://m.elecfans.com/article/774143.html

  9. openstack架构

    终于正式进入 OpenStack 部分了. 今天开始,CloudMan 将带着大家一步一步揭开 OpenStack 的神秘面纱. OpenStack 已经走过了 6 个年头. 每半年会发布一个版本,版 ...

  10. Eclipse安装颜色主题,个性化你的IDE,让你的IDE焕然一新

    我们都知道eclipse默认的颜色主题是白色的背景,但是如果想改变代码编辑区的背景颜色,需要怎么办呢? 今天给大家介绍一个非常赞的eclipse,可以很方便的根据自己的需求选择喜欢的颜色主题,其他的不 ...