【Python】【socket】
【server.py】
"""
#练习1
import socket
import threading sock = socket.socket()
sock.bind(('127.0.0.1',8889))
sock.listen(5) def tcplink(conn,addr):
# sock.sendall('Hello Socket'.encode('utf-8'))
conn.send(bytes('Hello world',encoding='utf-8'))
conn.close() while True:
conn, addr = sock.accept()
t = threading.Thread(target=tcplink,args=(conn,addr))
t.start() #练习2: 和机器人聊天 import socketserver class Myserver(socketserver.BaseRequestHandler):
def handle(self):
conn = self.request
conn.sendall(('你好,我是机器人').encode('utf-8'))
while True:
ret_bytes = conn.recv(1024)
ret_str = ret_bytes.decode('utf-8')
if ret_str == 'q':
break
conn.sendall((ret_str + '你好我好大家好').encode('utf-8')) if __name__ == '__main__':
server = socketserver.ThreadingTCPServer(('127.0.0.1',8888),Myserver)
server.serve_forever() #练习3 上传文件
import socket sk = socket.socket()
sk.bind(('127.0.0.1',8887))
sk.listen() while True:
conn,addr = sk.accept()
conn.sendall('欢迎光临我爱我家'.encode('utf-8')) size = conn.recv(1024)
size_str = size.decode('utf-8')
file_size = int(size_str) conn.sendall('开始传送'.encode('utf-8')) has_size = 0
f = open('db_new.JPG','wb')
while True:
if file_size == has_size:
break
date = conn.recv(1024)
f.write(date)
has_size += len(date) f.close() '''
参考:https://www.cnblogs.com/aylin/p/5572104.html “利用select实现伪同时处理多个Socket客户端请求”和“利用select实现伪同时处理多个Socket客户端读写分离”
下面两个例子我没跑通,只是想说明一下这个IO多路复用实现理论:SocketServer的ThreadingTCPServer之所以可以同时处理请求得益于 select 和 Threading 两个东西,其实本质上就是在服务器端为每一个客户端创建一个线程,当前线程用来处理对应客户端的请求,所以,可以支持同时n个客户端链接(长连接)
IO多路复用 I/O(input/output),即输入/输出端口。每个设备都会有一个专用的I/O地址,用来处理自己的输入输出信息首先什么是I/O:
I/O分为磁盘io和网络io,这里说的是网络io
IO多路复用:
I/O多路复用指:通过一种机制,可以监视多个描述符(socket),一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作。
Linux
Linux中的 select,poll,epoll 都是IO多路复用的机制。
Linux下网络I/O使用socket套接字来通信,普通I/O模型只能监听一个socket,而I/O多路复用可同时监听多个socket.
I/O多路复用避免阻塞在io上,原本为多进程或多线程来接收多个连接的消息变为单进程或单线程保存多个socket的状态后轮询处理.
Python
Python中有一个select模块,其中提供了:select、poll、epoll三个方法,分别调用系统的 select,poll,epoll 从而实现IO多路复用。
1
2
3
4
5
6
7
8
9
10
11
Windows Python: 提供: select Mac Python: 提供: select Linux Python: 提供: select、poll、epoll
对于select模块操作的方法:
1
2
3
4
5
6
7
8
9
10
11
句柄列表11, 句柄列表22, 句柄列表33 = select.select(句柄序列1, 句柄序列2, 句柄序列3, 超时时间) 参数: 可接受四个参数(前三个必须)
返回值:三个列表 select方法用来监视文件句柄,如果句柄发生变化,则获取该句柄。
1、当 参数1 序列中的句柄发生可读时(accetp和read),则获取发生变化的句柄并添加到 返回值1 序列中
2、当 参数2 序列中含有句柄时,则将该序列中所有的句柄添加到 返回值2 序列中
3、当 参数3 序列中的句柄发生错误时,则将该发生错误的句柄添加到 返回值3 序列中
4、当 超时时间 未设置,则select会一直阻塞,直到监听的句柄发生变化
5、当 超时时间 = 1时,那么如果监听的句柄均无任何变化,则select会阻塞 1 秒,之后返回三个空列表,如果监听的句柄有变化,则直接执行。
'''
# 练习4 利用select 实现我伪同时处理多个Socket客户端请求
import select
import socket sk1 = socket.socket()
sk1.bind(('127.0.0.1',8005))
sk1.listen() inpu = [sk1,]
while True:
r_list,w_list,e_list = select.select(inpu,[],[],1)
for sk in r_list:
if sk == sk1:
conn,addr = sk.accept()
inpu.append(sk)
else:
try:
ret = sk.recv(1024).decode('utf-8')
sk.sendall((ret + 'hao').encode('utf-8'))
except Exception as ex:
inpu.remove(sk) #练习5 SocketServer模块的Fork方式 windows上不行,MAC上没试过
from socketserver import TCPServer, ForkingMixIn, StreamRequestHandler
import time class Server(ForkingMixIn, TCPServer): # 自定义Server类
pass class MyHandler(StreamRequestHandler):
def handle(self): # 重载handle函数
addr = self.request.getpeername()
'Get connection from', addr # 打印客户端地址
time.sleep(5) # 休眠5秒钟
self.wfile.write('This is a ForkingMixIn tcp socket server') # 发送信息 host = ''
port = 1234
server = Server((host, port), MyHandler) server.serve_forever() # 开始侦听并处理连接 """ #更详细的,参考:http://blog.csdn.net/taiyang1987912/article/details/40376067 【client.py】
"""
#练习1
import socket sock = socket.socket()
sock.connect(('127.0.0.1',8889)) #ret = sock.recv(1024).decode('utf-8')
ret = str(sock.recv(1024),encoding='utf-8')
print(ret) sock.close() #练习2 和机器人聊天 import socket obj = socket.socket()
obj.connect(('127.0.0.1',8888)) ret_bytes = obj.recv(1024)
ret_str = ret_bytes.decode('utf-8')
print(ret_str) while True:
inp = input('你好请问您有什么问题? \n >>>')
if inp == 'q':
obj.sendall(inp.encode('utf-8'))
break
else:
obj.sendall(inp.encode('utf-8'))
ret_bytes = obj.recv(1024)
ret_str = ret_bytes.decode('utf-8')
print(ret_str) #练习3 上传文件 import socket
import os obj = socket.socket()
obj.connect(('127.0.0.1',8887)) ret_bytes = obj.recv(1024)
ret_str = ret_bytes.decode('utf-8')
print(ret_str) size = os.stat('yan.JPG').st_size
obj.sendall(str(size).encode('utf-8')) obj.recv(1024) with open('yan.jpg','rb') as f:
for line in f:
obj.sendall(line) ## 练习4 利用select 实现我伪同时处理多个Socket客户端请求
import socket obj = socket.socket()
obj.connect(('127.0.0.1',8003)) while True:
inp = input('Please(q\退出):\n>>>')
obj.sendall(inp.encode('utf-8'))
if inp == 'q':
break
ret = obj.recv(1024).decode('utf-8')
print(ret) #练习5 SocketServer模块的Fork方式 windows上不行,MAC上没试过
import socket s = socket.socket() # 生成一个socket对象
server = socket.gethostname()
port = 1234
s.connect((server, port)) # 连接服务器
s.recv(1024) # 读取数据
s.close() # 关闭连接 """
【Python】【socket】的更多相关文章
- 【python 字典、json】python字典和Json的相互转换
[python 字典.json]python字典和Json的相互转换 dump/dumps字典转换成json load/loadsjson转化成字典 dumps.loads直接输出字符 dump.lo ...
- 【Python成长之路】Python爬虫 --requests库爬取网站乱码(\xe4\xb8\xb0\xe5\xa)的解决方法【华为云分享】
[写在前面] 在用requests库对自己的CSDN个人博客(https://blog.csdn.net/yuzipeng)进行爬取时,发现乱码报错(\xe4\xb8\xb0\xe5\xaf\x8c\ ...
- 【Python成长之路】装逼的一行代码:快速共享文件
[Python成长之路]装逼的一行代码:快速共享文件 2019-10-26 15:30:05 华为云 阅读数 335 文章标签: Python编程编程语言程序员Python开发 更多 分类专栏: 技术 ...
- 【python之路35】网络编程之socket相关
Socket socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字"向网络发出请求或者应答网络请求. sock ...
- 【python之路42】web框架们的具体用法
Python的WEB框架 (一).Bottle Bottle是一个快速.简洁.轻量级的基于WSIG的微型Web框架,此框架只由一个 .py 文件,除了Python的标准库外,其不依赖任何其他模块. p ...
- 【Python成长之路】词云图制作
[写在前面] 以前看到过一些大神制作的词云图 ,觉得效果很有意思.如果有朋友不了解词云图的效果,可以看下面的几张图(图片都是网上找到的): 网上找了找相关的软件,有些软件制作 还要付费.结果前几天在大 ...
- 【Python成长之路】装逼的一行代码:快速共享文件【华为云分享】
[写在前面] 有时候会与同事共享文件,正常人的操作是鼠标右键,点击共享.其实有个装逼的方法,用python的一行代码快速实现基于http服务的共享方式. [效果如下] [示例代码] 在cmd窗口进入想 ...
- 【Python成长之路】从 零做网站开发 -- 基于Flask和JQuery,实现表格管理平台
[写在前面] 你要开发网站? 嗯.. 会Flask吗? 什么东西,没听过... 会JQuery吗? 是python的库吗 ? 那你会什么? 我会F12打开网站 好吧,那我们来写 ...
- 朴素贝叶斯算法源码分析及代码实战【python sklearn/spark ML】
一.简介 贝叶斯定理是关于随机事件A和事件B的条件概率的一个定理.通常在事件A发生的前提下事件B发生的概率,与在事件B发生的前提下事件A发生的概率是不一致的.然而,这两者之间有确定的关系,贝叶斯定理就 ...
- 【Python—字典的用法】创建字典的3种方法
#创建一个空字典 empty_dict = dict() print(empty_dict) #用**kwargs可变参数传入关键字创建字典 a = dict(one=1,two=2,three=3) ...
随机推荐
- 吴恩达讲了干货满满的一节全新AI课,全程手写板书充满诚意非常干货
吴恩达讲了干货满满的一节全新AI课,全程手写板书充满诚意非常干货 摘要: 目前,AI技术做出的经济贡献几乎都来自监督学习,也就是学习从A到B,从输入到输出的映射.现在,监督学习.迁移学习.非监督学习. ...
- CATALINA_OPTS和 JAVA_OPTS区别
在Tomcat的catalina.sh文件中的启停server脚本中都应用到了两个变量: CATALINA_OPTS和JAVA_OPTS.用于保存Tomcat运行所需的各种参数. 他们在文件中的注释如 ...
- eclipse 依赖别的 工程 断点进不去
maven Debug 发现进不了断点. 点击右键-->Properties-->Java Compiler-->Classfile Generation, 勾选上Add line ...
- 有道词典翻译(携带请求头和post参数请求)
一.静态爬取页面信息 有道翻译网址:http://fanyi.youdao.com/ 在翻译中输入python 找到接口和请求的方式 参数是From Data类型 需要把参数数据转换为字典, 复制粘贴 ...
- Makefile shell subst $(1)
MAKE_3_80_realpath = $(shell $(top_srcdir)/scripts/realpath.sh '$(subst $(SQUOTE),\\$(SQUOTE),$(1 ...
- python类的组合
类的组合,即在类实例化时,将另一个类的实例作为参数传入,这样可以将两个实例关联起来. 当类之间有显著不同,并且较小的类是较大的类所需要的组件时,用组合比较好. 例如,描述一个机器人类,这个大类是由很多 ...
- Eclipse中已安装的插件如何卸载
最近在Eclipse中安装了一个插件,导致Eclipse使用的时候有些问题,就找了资料,原来Eclipse中的插件也是可以卸载的. 方法是点击菜单“Help”,“Install New Softwar ...
- VC++ 使用ShellExecute函数调用邮箱客户端发送邮件(可以带附件)
之前写过一篇博文,通过MAPI实现调用邮箱客户端发送邮件带附件,当时对ShellExecute研究不深,以为ShellExecute不能带附件,因为项目需求原因(MAPI只能调用Foxmail和O ...
- eclipse启动时发生的Initializing Java Tooling错误
eclipse在启动发生An internal error occurred during: "Initializing Java Tooling". java.lang.Null ...
- javascript对文件的读写
整合了一下网上对于js实现文件读写的代码,但是该功能只能在ie浏览器下执行,另外有些电脑上的ie需要设置. 下面是写入代码: var fso = new ActiveXObject("Scr ...