【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) ...
随机推荐
- Android开发常见错误汇总
[错误信息] [2011-01-19 16:39:10 - ApiDemos] WARNING: Application does not specify an API level requireme ...
- Python3自定义日志类 mylog
#encoding=utf-8 import os, sysimport datetimeimport time class Mylog(object): # 根文件夹 root_dir = s ...
- PDF文档导出
代码如下: /// <summary> /// 获取html内容,转成PDF(注册) /// </summary> public void DownloadPDFByHTML( ...
- Java 注释规范
基本的要求: 1.注释形式统一 在整个应用程序中,使用具有一致的标点和结构的样式来构造注释.如果在其它项目中发现它们的注释规范与这份文档不同,按照这份规范写代码,不要试图在既成的规范系统中引入新的规范 ...
- BATJ等大厂最全经典面试题分享
金九银十,又到了面试求职高峰期,最近有很多网友都在求大厂面试题.正好我之前电脑里面有这方面的整理,于是就发上来分享给大家. 这些题目是网友去百度.蚂蚁金服.小米.乐视.美团.58.猎豹.360.新浪. ...
- NGINX转发代理情况下,获取客户单真实IP
编译时加上http_realip_module 模块 realip模块生效的前提是:直接连接nginx的ip是在set_real_ip_from中指定的. 原机配置: set_real_ip_from ...
- java使用wait(),notify(),notifyAll()实现等待/通知机制
public class WaitNotify { static boolean flag=true; static Object lock=new Object(); static class Wa ...
- 【题解】Luogu P1648 看守
原题传送门:P1648 看守 这题目让求得的是d维( d <=4 )空间中n个点( 2 <= N <= 1000000 )之间最大的哈曼顿距离 模拟,emm,能拿30分,不错 因为d ...
- Kali系列之Hydra/Medusa mysql密码爆破
hydra hydra -L /home/chenglee/zidian/user.txt -P /home/chenglee/zidian/wordlist.TXT 192.168.137.133 ...
- [c/c++] programming之路(2)、kill QQ,弹出系统对话框,吃内存等
一.删除文件 二.盗取密码的原理 #include<stdlib.h> //杀掉QQ,然后提示网络故障,请重新登陆,弹出高仿界面,获取账号密码,然后打开QQ进行登录 void main() ...