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

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

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

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

# 代码如下:

Server

 __author__ = 'Stone'
# -*- coding: UTF-8 -*-
# !/usr/bin/env python3
import socket
import queue
import select
HOST = '0.0.0.0'
PORT = 8000
s = socket.socket()
s.bind((HOST,PORT))
s.listen(500)
# 设定关闭程序后,能马上释放服务器的端口,供后续程序使用
s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
s.setblocking(0) # 设置为非阻塞模式
# 设置列表,新建、发送、异常
inputs = []
outputs = []
#exceptions = []
# 存放信息
msg_dic = {}
inputs.append(s) # 把自身加进去,侦听是否有新连接
while True:
readable,writable,exceptional = select.select(inputs,outputs,inputs) # select 会阻塞socket
22
for r in readable:
if r is s:
# 说明有新连接过来
conn,addr = s.accept()
print("新连接:",addr)
conn.setblocking(0) # 把单个连接也设置为非阻塞模式,比如:某个连接接收的文件比较大,将会一直占用着(别的程序没机会处理);设置为非阻塞后,可以等着下次for循环继续接收
inputs.append(conn)
msg_dic[conn] = queue.Queue() # 为每个连接创建消息队列
else:
# 说明有连接是活动的
try:
data = r.recv(1024)
if data:
print("接收到了数据:",data.decode('utf-8'))
# 放进消息队列
msg_dic[r].put(data)
if r not in outputs:
outputs.append(r) # 并放入发送数据列表
else:
# 连接断开
print("客户端断开连接")
if r in outputs:
outputs.remove(r)
inputs.remove(r)
del msg_dic[r]
except socket.error: # 解决问题(出现客户端异常断开,服务器也跟着断开),后面不做任何处理,留给exceptional做处理
pass for w in writable:
try:
send_msg = msg_dic[w].get_nowait()
except queue.Empty:
print("client [%s]"% w.getpeername()[0],"queue is empty...")
outputs.remove(w)
else:
print("sending message to [%s]"% w.getpeername()[0],send_msg)
w.send(send_msg)
outputs.remove(w) # 防止再次执行时,发生empty的异常 for e in exceptional:
if e in outputs:
outputs.remove(e)
inputs.remove(e)
e.close()
del msg_dic[e]
s.close() Client:
 __author__ = 'Stone'
# -*- coding: UTF-8 -*-
# !/usr/bin/env python3
import socket
HOST = 'localhost'
PORT = 8000
s_client = socket.socket()
s_client.connect((HOST,PORT))
while True:
data = input('>>:').strip()
if not data:
continue
s_client.send(data.encode('utf-8'))
recv = s_client.recv(1024)
print(recv)
#break # 测试,作为客户端自动离开
s_client.close()
												

最新文章

  1. ngx_http_uwsgi_module模块.md
  2. 简单而又复杂的jsp(小知识)
  3. pyspider安装
  4. Linux的硬链接为何不能链接目录
  5. neutron中的dhcp功能
  6. 【原】cocos2d-x开发笔记:多点触控
  7. A在SP.NET跨页多选
  8. TFS-Git官方教程
  9. HDU 2568[前进]模拟
  10. 文本域、bootstrap-table显示以及MySQL三者间的换行符问题
  11. BZOJ_2223_[Coci 2009]PATULJCI_主席树
  12. Qt学习3---子窗口与父窗口
  13. Dom 兼容处理
  14. java之类的初始化
  15. Linux wget 命令下载文件
  16. 个人总结-----非贪心算法的图的m着色判断及优化问题
  17. 10 Maven 版本管理
  18. APMServ—优秀的PHP集成环境工具
  19. ZBar之ZBarReaderViewController
  20. Django 版本对应的 Python 版本

热门文章

  1. spring cloud 系列第2篇 —— eureka 高可用注册中心的搭建 (F版本)
  2. 【mysql5.7】远程无法连接设置
  3. webpack打包(一)
  4. WebGL概述
  5. Python将mongodb导出的bson文件转为字典对象
  6. 整理一下Apache与Tomcat的关系
  7. yarn or npm 版本固化如何选择
  8. POJ 2887:Big String(分块)
  9. 关于在记事本写入"\n"不显示换行的原因
  10. React躬行记(8)——样式