python利用select实现的Socket Server

# 利用python的select模块实现简单的Socket Sever

#实现多用户访问,再次基础上可以实现FTP Server应用程序

# 发布目的,在于解决了客户端强行终止时,服务器端也跟着程序终止

# 程序的关键在:读就是读,写就是写 ,不要读写混着来

# 代码如下:

Server

 1 __author__ = 'Stone'
 2 # -*- coding: UTF-8 -*-
 3 # !/usr/bin/env python3
 4 import socket
 5 import queue
 6 import select
 7 HOST = '0.0.0.0'
 8 PORT = 8000
 9 s = socket.socket()
10 s.bind((HOST,PORT))
11 s.listen(500)
12 # 设定关闭程序后,能马上释放服务器的端口,供后续程序使用
13 s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
14 s.setblocking(0) # 设置为非阻塞模式
15 # 设置列表,新建、发送、异常
16 inputs = []
17 outputs = []
18 #exceptions = []
19 # 存放信息
20 msg_dic = {}
21 inputs.append(s)  # 把自身加进去,侦听是否有新连接
22 while True:
23     readable,writable,exceptional = select.select(inputs,outputs,inputs)  # select 会阻塞socket
22
25     for r in readable:
26         if r is s:
27             # 说明有新连接过来
28             conn,addr = s.accept()
29             print("新连接:",addr)
30             conn.setblocking(0) # 把单个连接也设置为非阻塞模式,比如:某个连接接收的文件比较大,将会一直占用着(别的程序没机会处理);设置为非阻塞后,可以等着下次for循环继续接收
31             inputs.append(conn)
32             msg_dic[conn] = queue.Queue()  # 为每个连接创建消息队列
33         else:
34             # 说明有连接是活动的
35                 try:
36                     data = r.recv(1024)
37                     if data:
38                         print("接收到了数据:",data.decode('utf-8'))
39                         # 放进消息队列
40                         msg_dic[r].put(data)
41                         if r not in outputs:
42                             outputs.append(r)  # 并放入发送数据列表
43                     else:
44                         # 连接断开
45                         print("客户端断开连接")
46                         if r in outputs:
47                             outputs.remove(r)
48                         inputs.remove(r)
49                         del msg_dic[r]
50                 except socket.error:     # 解决问题(出现客户端异常断开,服务器也跟着断开),后面不做任何处理,留给exceptional做处理
51                     pass
52 
53     for w in writable:
54         try:
55             send_msg = msg_dic[w].get_nowait()
56         except queue.Empty:
57             print("client [%s]"% w.getpeername()[0],"queue is empty...")
58             outputs.remove(w)
59         else:
60             print("sending message to [%s]"% w.getpeername()[0],send_msg)
61             w.send(send_msg)
62             outputs.remove(w)  # 防止再次执行时,发生empty的异常
63 
64     for e in exceptional:
65         if e in outputs:
66             outputs.remove(e)
67         inputs.remove(e)
68         e.close()
69         del msg_dic[e]
70 s.close()

Client:
 1 __author__ = 'Stone'
 2 # -*- coding: UTF-8 -*-
 3 # !/usr/bin/env python3
 4 import socket
 5 HOST = 'localhost'
 6 PORT = 8000
 7 s_client = socket.socket()
 8 s_client.connect((HOST,PORT))
 9 while True:
10     data = input('>>:').strip()
11     if not data:
12         continue
13     s_client.send(data.encode('utf-8'))
14     recv = s_client.recv(1024)
15     print(recv)
16     #break      # 测试,作为客户端自动离开
17 s_client.close()

 

 


posted @ 2018-06-01 17:12  流放的圣徒  阅读(1678)  评论(0编辑  收藏  举报