【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) ...
随机推荐
- RBAC
什么是rbac? -- 基于角色的权限控制 Role-Based Access Control 一个url就代表一个权限 // url分配给角色,角色分配给用户 -- 6个model,4张表 菜单表 ...
- Matlab基础部分1
- 在CentOS 6.3中安装与配置cmake
安装说明安装环境:CentOS-6.3安装方式:源码编译安装软件:cmake-2.8.10.2.tar.gz下载地址:http://www.cmake.org/cmake/resources/soft ...
- 编写一个JavaWeb项目
基本流程:JSP文件显示页面,在前端页面输入赋值,使用form或href超链接传值到Servlet中方法,在Servlet方法中调用Dao层的类对象,将数据传到数据库中,并实现对数据库里的数据的增删改 ...
- scala语言中的case关键字在spark中的一个奇特使用
package com.spark.demo import com.spark.demo.util.SparkUtil import org.apache.spark.rdd.RDD import s ...
- qt中QtreeWidget与QstackWidget关联的问题
过程:要做一个图书管理系统,主界面是类似于这样的 左边是类似于树形空间的东西,当点击左边的左边的窗体的时候,右边的窗口也会跟着切换. 为了实现这个功能,必须要有两个控件,QTreeWidget和Qst ...
- Zynq ZC706 传统方式移植Linux -- 编译u-boot
我用的是zc706不是zed 基本思路是: 1.安装交叉编译工具(见 https://www.cnblogs.com/idyllcheung/p/10532654.html ) 2.下载xilinx ...
- laravel 数据库 - 增删查改
//查询public function select(){ /** 数据表 CREATE TABLE `student` ( `id` int(11) NOT NULL AUTO_INCREMENT, ...
- selenium使用location定位元素坐标偏差
python+selenium+Chromedriver使用location定位元素坐标偏差使用xpath定位元素,用.location获取坐标值,截取网页截图的一部分出现偏差. 之所以会出现这个坐标 ...
- innobackup stream 压缩备份,解压后的qp文件
是用innobackup stream 压缩备份,解压后很多文件还是qp格式的压缩文件,需要再解压. 备份: [root@ ~]# /usr/bin/innobackupex --defaults-f ...