Python-Day9

select服务器:

  1 #!/usr/bin/env pyhton3
  2 # -*- coding:utf-8 -*-
  3 __author__ = 'songge1209'
  4 
  5 import select
  6 import socket
  7 import sys
  8 import queue
  9 
 10 #生成socket句柄,指定socket.AF_INET为网络通信,socket.SOCK_STREAM基于TCP连接,不指定默认也是这两个
 11 server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
 12 #设置不阻塞,False和0为不阻塞,True和1为阻塞
 13 server.setblocking(False)
 14 
 15 #以元组形式将服务器地址和端口赋值给变量server_address
 16 server_address = ("localhost",10000)
 17 #打印错误
 18 print(sys.stderr,"starting up on %s port %s" % server_address)
 19 #为服务器绑定IP和端口
 20 server.bind(server_address)
 21 
 22 #指定客服端最大连接数为5
 23 server.listen(5)
 24 
 25 #定义输入列表,把socket句柄放入列表
 26 inputs = [server]
 27 
 28 #定义输出列表,初始为空
 29 outputs = []
 30 
 31 #定义消息队列,初始为空字典
 32 message_queues = {}
 33 #定义while循环,输入列表为空时,循环结束
 34 while inputs:
 35 
 36     #打印信息
 37     print("\nwaiting for the next event")
 38     #调用select模块的select方法监控输入,输出列表,并赋值给可读,可写,错误列表
 39     readable,writeable,exceptional = select.select(inputs,outputs,inputs)
 40 
 41     #for循环可读列表
 42     for s in readable:
 43 
 44         #若可读列表中元素是sockect句柄,表示用新连接
 45         if s is server:
 46             #接受新连接
 47             connection,client_address = s.accept()
 48             #打印连接客户端地址
 49             print("new connection from ",client_address)
 50             #连接设置为不阻塞
 51             connection.setblocking(False)
 52             #把连接追加到输入列表,下次while循环时select监控连接状态
 53             inputs.append(connection)
 54             #在消息队列字典中,以连接为KEY,生成一个独立的消息队列为值
 55             message_queues[connection] = queue.Queue()
 56 
 57         #不是server,代表某连接有数据发来
 58         else:
 59             #接收数据赋值给data
 60             data = s.recv(1024).decode("utf8")
 61             #如果有数据
 62             if data:
 63                 #打印数据, s.getpeername()返回客户端地址和端口;(s.getsockname()返回本地服务器地址和端口)
 64                 print(sys.stderr,"received %s from %s " % (data, s.getpeername()))
 65                 #若直接返回会阻塞其他连接进来,所以先不返回,把数据赋值给该连接的消息队列
 66                 message_queues[s].put(data)
 67 
 68                 #连接不在输出列表时:
 69                 if s not in outputs:
 70                     #把连接追加到输出列表
 71                     outputs.append(s)
 72             #没有接收到数据,可能是出错了
 73             else:
 74                 #打印关闭该连接信息
 75                 print("closing",client_address,"after reading not data")
 76                 #出错了就需要关闭连接,同时清除掉这个连接的注册信息,如果在输出列表
 77                 if s in outputs:
 78                     #就从列表中删除掉
 79                     outputs.remove(s)
 80                 #输入列表中也把此连接删除
 81                 inputs.remove(s)
 82                 #关闭连接
 83                 s.close()
 84                 #消息队列字典中也清除掉此链接信息
 85                 del message_queues[s]
 86 
 87     #循环可写列表:
 88     for s in writeable:
 89         #判断下面执行有无异常
 90         try:
 91             #从该连接的消息队列取数据
 92             next_msg = message_queues[s].get_nowait()
 93         #若该连接的消息队列为空时,捕获执行以下操作
 94         except queue.Empty:
 95             #打印此连接的信息和队列为空
 96             print("output queue for",s.getpeername(),"is empty")
 97             #清除输出列表中的此链接
 98             outputs.remove(s)
 99         #不为空,取到数据
100         else:
101             #打印发送数据信息和客户端信息
102             print("sending %s to %s " % (next_msg,s.getpeername()))
103             #发送给客户端
104             s.send(next_msg.encode("utf8"))
105 
106     #当客户端断开连接,会产生错误,循环错误列表
107     for s in exceptional:
108         #打印错误信息
109         print("handling exceptional condition for", s.getpeername())
110         #删除输入列表中的此连接
111         inputs.remove(s)
112         #如果此连接在输出列表中
113         if s in outputs:
114             #删除此连接
115             outputs.remove(s)
116         #关闭这个连接
117         s.close()
118         #如果在消息队列字典中有这个连接
119         if message_queues[s]:
120             #删除这个连接
121             del message_queues[s]
View Code

 

select客户端:

 1 #!/usr/bin/env pyhton3
 2 # -*- coding:utf-8 -*-
 3 __author__ = 'songge1209'
 4 
 5 import socket
 6 import sys
 7 
 8 #定义信息列表
 9 messages = ["This is the message.",
10             "It will be sent",
11             "in parts.",
12 ]
13 
14 #指定要连接的服务器地址和端口
15 server_address = ("localhost",10000)
16 
17 #定义一个连接列表,指定连接方式,创建连接
18 socks = [socket.socket(socket.AF_INET,socket.SOCK_STREAM),
19          socket.socket(socket.AF_INET,socket.SOCK_STREAM),
20 ]
21 
22 #如果有错误,输出错误
23 print(sys.stderr,"connection to %s port %s" % server_address)
24 #循环连接列表
25 for s in socks:
26     #连接服务器
27     s.connect(server_address)
28 
29 #循环信息列表
30 for message in messages:
31     #循环连接服务器列表
32     for s in socks:
33         #如果有错误,输出错误信息,s.getsockname()返回本地地址和端口
34         print(sys.stderr,"%s: sending %s" % (s.getsockname(),message))
35         #给服务器发送信息
36         s.send((message).encode("utf8"))
37 
38     #循环连接服务器列表
39     for s in socks:
40         #接收数据赋值给data
41         data = s.recv(1024).decode("utf8")
42         #如果有错误,输出错误信息
43         print(sys.stderr,"%s: received %s" % (s.getsockname(),message))
44         #如果没有接收到数据
45         if not data:
46             #打印关闭信息
47             print(sys.stderr,"closing socket %s" ,s.getsockname())
48             #关闭连接
49             s.close()
View Code

 

posted @ 2016-03-23 22:52  songge1209  阅读(72)  评论(0编辑  收藏  举报