还有很多缺限, 如客户断开无限重复
以下转至老师博客:
- server:
- #!/usr/bin/env python
- # -*- coding: utf-8 -*-
- __author__ = "alex"
- import select
- import socket
- import sys
- import queue
- server = socket.socket()
- server.setblocking(0)
- server_addr = ('localhost',5000)
- print('starting up on %s port %s' % server_addr)
- server.bind(server_addr)
- server.listen(5)
- inputs = [server, ] #自己也要监测呀, 因为 server 本身也是个 fd
- outputs = []
- message_queues = {}
- while True:
- print("waiting for next event...")
- readable, writeable, exeptional = select.select(inputs,outputs,inputs) #如果没有任何 fd 就绪, 那程序就会一直阻塞在这里
- for s in readable: #每个 s 就是一个 socket
- if s is server: #别忘记, 上面我们 server 自己也当做一个 fd 放在了 inputs 列表里, 传给了 select, 如果这个 s 是 server, 代表 server 这个 fd 就绪了,
- #就是有活动了, 什么情况下它才有活动? 当然 是有新连接进来的时候 呀
- #新连接进来了, 接受这个连接
- conn, client_addr = s.accept()
- print("new connection from",client_addr)
- conn.setblocking(0)
- inputs.append(conn) #为了不阻塞整个程序, 我们不会立刻在这里开始接收客户端发来的数据, 把它放到 inputs 里, 下一次 loop 时, 这个新连接
- #就会被交给 select 去监听, 如果这个连接的客户端发来了数据 , 那这个连接的 fd 在 server 端就会变成就续的, select 就会把这个连接返回, 返回到
- #readable 列表里, 然后你就可以 loop readable 列表, 取出这个连接, 开始接收数据了, 下面就是这么干 的
- message_queues[conn] = queue.Queue() #接收到客户端的数据后, 不立刻返回 , 暂存在队列里, 以后发送
- else: #s 不是 server 的话, 那就只能是一个 与客户端建立的连接的 fd 了
- #客户端的数据过来了, 在这接收
- data = s.recv(1024)
- if data:
- print("收到来自 [%s] 的数据:" % s.getpeername()[0], data)
- message_queues[s].put(data) #收到的数据先放到 queue 里, 一会返回给客户端
- if s not in outputs:
- outputs.append(s) #为了不影响处理与其它客户端的连接 , 这里不立刻返回数据给客户端
- else:# 如果收不到 data 代表什么呢? 代表客户端断开了呀
- print("客户端断开了",s)
- if s in outputs:
- outputs.remove(s) #清理已断开的连接
- inputs.remove(s) #清理已断开的连接
- del message_queues[s] ## 清理已断开的连接
- for s in writeable:
- try :
- next_msg = message_queues[s].get_nowait()
- except queue.Empty:
- print("client [%s]" %s.getpeername()[0], "queue is empty..")
- outputs.remove(s)
- else:
- print("sending msg to [%s]"%s.getpeername()[0], next_msg)
- s.send(next_msg.upper())
- for s in exeptional:
- print("handling exception for",s.getpeername())
- inputs.remove(s)
- if s in outputs:
- outputs.remove(s)
- s.close()
- del message_queues[s]
- client:
- __author__ = "alex"
- import socket
- import sys
- messages = [ b'This is the message.',
- b'It will be sent',
- b'in parts.',
- ]
- server_address = ('localhost', 5000)
- # Create a TCP/IP socket
- socks = [ socket.socket(socket.AF_INET, socket.SOCK_STREAM),
- socket.socket(socket.AF_INET, socket.SOCK_STREAM),
- ]
- # Connect the socket to the port where the server is listening
- print('connecting to %s port %s' % server_address)
- for s in socks:
- s.connect(server_address)
- for message in messages:
- # Send messages on both sockets
- for s in socks:
- print('%s: sending"%s"' % (s.getsockname(), message) )
- s.send(message)
- # Read responses on both sockets
- for s in socks:
- data = s.recv(1024)
- print( '%s: received"%s"' % (s.getsockname(), data) )
- if not data:
- print(sys.stderr, 'closing socket', s.getsockname() )
- ...
来源: http://www.bubuko.com/infodetail-2614586.html