码迷,mamicode.com
首页 > 其他好文 > 详细

用select模拟一个socket server

时间:2017-08-17 22:52:57      阅读:277      评论:0      收藏:0      [点我收藏+]

标签:connect   finish   data   sock   3.5   back   except   recv   操作   

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.

 

用select模拟一个socket server

标签:connect   finish   data   sock   3.5   back   except   recv   操作   

原文地址:http://www.cnblogs.com/momo8238/p/7384699.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!