正文
Python socket & socket server
小程序:扫一扫查出行
【扫一扫了解最新限行尾号】
复制小程序
【扫一扫了解最新限行尾号】
复制小程序
socket
网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket(套接字)。
建立网络通信连接至少要一对socket。socket是对TCP/IP的封装
使用方法
步骤:
服务器端:
- 实例化类
- bind 绑定端口
- listen 监听端口
-
accept 等待连接(阻塞)
sock, addr = server.accept()
sock 是为客户端实例化的socket类, addr 是客户端的地址 - 与客户端交互:recv 接收(阻塞)、send 发送数据
- close 断开连接
客户端:
- 实例化类
- connect 连接端口
- 与服务器端交互:recv 接收(阻塞)、send 发送数据
- close 断开连接
只传输一条数据
server:
import socket
server = socket.socket()
server.bind(('localhost', 8001))
server.listen(3)
conn, addr = server.accept()
data = conn.recv(1024)
conn.send(b'Got')
print('recv:', data)
server.close()
client:
import socket
client = socket.socket()
client.connect(('localhost', 8001))
client.send(b'Hello')
data = client.recv(1024)
print('recv:', data)
client.close()
循环发送数据:
server:
import socket
server = socket.socket()
server.bind(('localhost', 8001))
server.listen(3)
while 1:
conn, addr = server.accept()
print('new connection:', addr)
while 1:
data = conn.recv(1024)
conn.send(b'Got')
if not data:
break
else:
print('recv:', data)
client:
import socket
client = socket.socket()
client.connect(('localhost', 8001))
while 1:
data = input('>>>').strip()
if len(data) == 0:
# 注意不能发送内容为空,否则客户端会卡住
continue
if data == 'e':
break
else:
client.send(data.encode('utf-8'))
data = client.recv(1024)
print('recv:', data.decode())
client.close()
模拟SSH
server:
import socket
import os
server = socket.socket()
server.bind(('localhost', 8001))
server.listen(3)
while 1:
try:
conn, addr = server.accept()
print('new connection:', addr)
while 1:
data = conn.recv(1024)
if not data:
break
else:
res = os.popen(data.decode()).read()
conn.send(res.encode())
except ConnectionResetError:
continue
client:
import socket
client = socket.socket()
client.connect(('localhost', 8001))
while 1:
data = input('>>>').strip()
if len(data) == 0:
# 注意不能发送内容为空,否则客户端会卡住
continue
if data == 'e':
break
else:
client.send(data.encode('utf-8'))
data = client.recv(1024)
print(data.decode())
client.close()
socket 粘包
当 send 被调用时,数据其实并没有立刻被发送给客户端,而是放到了系统的 socket 发送缓冲区里,等缓冲区满了、或者数据等待超时了,数据才会被 send 到客户端,这样就把好几次的小数据拼成一个大数据,统一发送到客户端了,这么做的目地是为了提高IO利用效率,一次性发送总比连发好几次效率高嘛。但也带来一个问题,就是“粘包”,即2次或多次的数据粘在了一起统一发送了。
解决方法:
- 让数据等待超时,发送一次数据之后 sleep(0.5) (直接忽略)
- 不要连续 send ,可以用 recv 将多次 send 隔开,只需要数据接收端接收到一次数据后,send 回复发送端
- 如果之前知道传输数据的大小,直接接收那么多的数据
传输大文件
server:
import socket
import os
import hashlib
server = socket.socket()
server.bind(('localhost', 8001))
server.listen(3)
while 1:
try:
conn, addr = server.accept()
print('new connection:', addr)
while 1:
cmd = conn.recv(1024).decode()
if not cmd:
print('lost client')
break
else:
file_name = cmd.split()[1]
if not os.path.isfile(file_name):
res = 'no such file'
else: # 存在可以传输的文件
m = hashlib.md5()
file_size = os.stat(file_name).st_size
print(file_size)
conn.send(str(file_size).encode())
conn.recv(1024)
with open(file_name, 'rb')as f:
for line in f:
conn.send(line)
m.update(line)
print('file md5:', m.hexdigest())
conn.send(m.hexdigest().encode())
except ConnectionResetError:
print('lost client')
continue
client:
import socket
import hashlib
client = socket.socket()
client.connect(('localhost', 8001))
while 1:
cmd = input('get filename: >>>').strip()
if len(cmd) == 0:
# 注意不能发送内容为空,否则客户端会卡住
continue
else:
client.send(cmd.encode('utf-8'))
file_name = cmd.split()[1]
received_size = 0
m = hashlib.md5()
total_size = client.recv(1024)
client.send(b'Get size')
f = open(file_name + '.new', 'wb')
while received_size < int(total_size.decode()):
size = int(total_size.decode()) - received_size
if size < 1024:
receive_size = size
else:
receive_size = 1024
data = client.recv(receive_size)
received_size += len(data)
f.write(data)
m.update(data)
else:
f.close()
print(m.hexdigest())
server_md5 = client.recv(1024).decode()
if m.hexdigest() == server_md5:
print('file checked')
client.close()
有时结束连接之后再连接会显示端口占用,可以通过重用端口省去等待的时间:
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
(bind 端口之前进行设置)
socket server
创建socketserver的基本步骤:
- 创建一个请求处理类,继承 BaseRequestHandler 并且重写父类中的 handle()
- 实例化 TCPServer ,将 server IP 和请求处理类传给 TCPServer
-
调用
server.handle_request() #只处理一个请求
server.serve_forever() #处理多个一个请求,永远执行
- server_close()
继承关系
class BaseServer:
class TCPServer(BaseServer):
class UDPServer(TCPServer):
class UnixStreamServer(TCPServer):
class UnixDatagramServer(UDPServer):
class ThreadingUDPServer(ThreadingMixIn, UDPServer): pass
class ThreadingTCPServer(ThreadingMixIn, TCPServer): pass
使用方法
import socketserver
class MyTCPHandler(socketserver.BaseRequestHandler):
def handle(self):
# 处理和客户端所有的交互
pass
if __name__ == '__main__':
HOST, PORT = 'localhost', 8001
server = socketserver.TCPServer((HOST, PORT), MyTCPHandler)
server.serve_forever()
如果要设置允许地址重用:
allow_reuse_address
是 TCPServer 和 UDPServer 的类变量,之后又被实例化的类继承了,由于实例化的类继承父类的同时已经开始 bind,所以只能在他继承父类之前修改父类的类变量
HOST, PORT = 'localhost', 8001
socketserver.TCPServer.allow_reuse_address = True
server = socketserver.TCPServer((HOST, PORT), MyTCPHandler) # 实例化 bind listen
server.serve_forever()
socket server 多并发
多线程:
ThreadingTCPServer
多进程:
ForkingTCPServer
-only in Linux
使用时只需在实例化类时继承其中一个:
HOST, PORT = 'localhost', 8001
socketserver.TCPServer.allow_reuse_address = True
server = socketserver.ThreadingTCPServer((HOST, PORT), MyTCPHandler) # 实例化 bind listen
server.serve_forever()
Python socket & socket server的更多相关文章
-
Python中socket经ssl加密后server开多线程
前几天手撸Python socket代码,撸完之后经过ssl加密,确保数据的安全,外加server端开启多线程保证一个客户端连接有一个线程来服务客户端,走了不少的弯路,网上的信息啥的要 ...
-
Python socket 基础(Server) - Foundations of Python Socket
Python socket 基础 Server - Foundations of Python Socket 通过 python socket 模块建立一个提供 TCP 链接服务的 server 可分 ...
-
python从socket做个websocket的聊天室server
下面的是server端:把IP改成自己的局域网IP: #coding:utf8 import socket,select import SocketServer import hashlib,base ...
-
python之Socket网络编程
什么是网络? 网络是由节点和连线构成,表示诸多对象及其相互联系.在数学上,网络是一种图,一般认为专指加权图.网络除了数学定义外,还有具体的物理含义,即网络是从某种相同类型的实际问题中抽象出来的模型.在 ...
-
python之socket-ssh实例
本文转载自大王http://www.cnblogs.com/alex3714/articles/5830365.html 加有自己的注释,应该会比原文更突出重点些 一. 基本Socket实例 前面讲了 ...
-
python之socket
一.初识socket socket 是网络连接端点,每个socket都被绑定到一个特定的IP地址和端口.IP地址是一个由4个数组成的序列,这4个数均是范围 0~255中的值(例如, ...
-
Python:socket
Socket:又称"套接字",应用程序通常通过"套接字"向网络发出请求或者应答网络请求,使主机间或者一台计算机上的进程间可以通讯. socket()函数 Pyt ...
-
python之socket开发
socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字"向网络发出请求或者应答网络请求. socket起源于Un ...
-
Python网络socket学习
Python 网络编程 Python 提供了两个级别访问的网络服务.: 低级别的网络服务支持基本的 Socket,它提供了标准的 BSD Sockets API,可以访问底层操作系统Socket接口的 ...
随机推荐
-
acwing 55. 连续子数组的最大和
地址 https://www.acwing.com/problem/content/50/ 输入一个 非空 整型数组,数组里的数可能为正,也可能为负. 数组中一个或连续的多个整数组成一个子数组. 求 ...
-
【转】bootstrap table轻松实现数据表格
在使用bootstrap table时可能在很多时候回用的表格来显示数据,如果自己写那肯定没问题,但是数据展示出来就麻烦多了,然而bootstrap table 封装了一套完善的数据表格组件,把从后台 ...
-
BZOJ1369/LG4395 「BOI2003」Gem 树形DP
问题描述 LG4395 BZOJ1369 题解 发现对于结点 \(x\) ,其父亲,自己,和所有的孩子权值不同,共 \(3\) 类,从贪心的角度考虑,肯定是填 \(1,2,3\) 这三种. 于是套路树 ...
-
给用户提供就医帮助的安卓APP
经过我们的小组的成员讨论,我们确定了我们小组的项目,即是一款给用户提供就医帮助的安卓APP. 项目计划及功能:计划两个月内团队成员共同开发完成此款APP,此款APP提供预约挂号,名医名院咨询, 就医导 ...
-
Eclipse maven创建web项目报错Could not resolve archetype
1.下载http://repo1.maven.org/maven2/archetype-catalog.xml 通过eclipse下载和网页下载我这里都比较慢,最后用的迅雷下载 2.将本地xml文件配 ...
-
【swoole】结合swoole 和 nsq 的实际应用
集合 swoole 的框架设计 为了减少理解度,我尽量的从源头开始引入 1. nsq 案例中是使用 swoole 结合一个php 框架实现的是 NSQ 订阅功能. 启动命令: sudo bash /w ...
-
ASP.NET Core框架深度学习(四)宿主对象
11.WebHost 第六个对象 到目前为止我们已经知道了由一个服务器和多个中间件构成的管道是如何完整针对请求的监听.接收.处理和最终响应的,接下来来讨论这样的管道是如何被构建出来的.管道是在作为应 ...
-
HashMap、ConcurrentHashMap解析
一.HashMap分析 在JDK1.8之前,hashMap由数组+链表组成,1.8之后,对hashMap进行了一些修改,最大的不同就是利用了红黑树,所以其由数组+链表+红黑树组成.查找时,根据hash ...
-
LD_PRELOAD & putenv() 绕过 disable_functions & open_basedir
这次TCTF中一道题,给出了一个PHP一句话木马,设置了open_basedir,disable_functions包含所有执行系统命令的函数,然后目标是运行根目录下的/readflag,目标很明确, ...
-
顺F分享,你是在裸奔吗?
" 对顺F旗下各APP顺藤摸瓜分析--顺F分享." 前文对顺F速运和顺F速运国际版进行了分析,二者使用同一套接口,虽然保护强度不高,但对代码和数据的保护却区别对待,实在让人诧异. ...
前几天手撸Python socket代码,撸完之后经过ssl加密,确保数据的安全,外加server端开启多线程保证一个客户端连接有一个线程来服务客户端,走了不少的弯路,网上的信息啥的要 ...
Python socket 基础 Server - Foundations of Python Socket 通过 python socket 模块建立一个提供 TCP 链接服务的 server 可分 ...
下面的是server端:把IP改成自己的局域网IP: #coding:utf8 import socket,select import SocketServer import hashlib,base ...
什么是网络? 网络是由节点和连线构成,表示诸多对象及其相互联系.在数学上,网络是一种图,一般认为专指加权图.网络除了数学定义外,还有具体的物理含义,即网络是从某种相同类型的实际问题中抽象出来的模型.在 ...
本文转载自大王http://www.cnblogs.com/alex3714/articles/5830365.html 加有自己的注释,应该会比原文更突出重点些 一. 基本Socket实例 前面讲了 ...
一.初识socket socket 是网络连接端点,每个socket都被绑定到一个特定的IP地址和端口.IP地址是一个由4个数组成的序列,这4个数均是范围 0~255中的值(例如, ...
Socket:又称"套接字",应用程序通常通过"套接字"向网络发出请求或者应答网络请求,使主机间或者一台计算机上的进程间可以通讯. socket()函数 Pyt ...
socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字"向网络发出请求或者应答网络请求. socket起源于Un ...
Python 网络编程 Python 提供了两个级别访问的网络服务.: 低级别的网络服务支持基本的 Socket,它提供了标准的 BSD Sockets API,可以访问底层操作系统Socket接口的 ...
-
acwing 55. 连续子数组的最大和
地址 https://www.acwing.com/problem/content/50/ 输入一个 非空 整型数组,数组里的数可能为正,也可能为负. 数组中一个或连续的多个整数组成一个子数组. 求 ...
-
【转】bootstrap table轻松实现数据表格
在使用bootstrap table时可能在很多时候回用的表格来显示数据,如果自己写那肯定没问题,但是数据展示出来就麻烦多了,然而bootstrap table 封装了一套完善的数据表格组件,把从后台 ...
-
BZOJ1369/LG4395 「BOI2003」Gem 树形DP
问题描述 LG4395 BZOJ1369 题解 发现对于结点 \(x\) ,其父亲,自己,和所有的孩子权值不同,共 \(3\) 类,从贪心的角度考虑,肯定是填 \(1,2,3\) 这三种. 于是套路树 ...
-
给用户提供就医帮助的安卓APP
经过我们的小组的成员讨论,我们确定了我们小组的项目,即是一款给用户提供就医帮助的安卓APP. 项目计划及功能:计划两个月内团队成员共同开发完成此款APP,此款APP提供预约挂号,名医名院咨询, 就医导 ...
-
Eclipse maven创建web项目报错Could not resolve archetype
1.下载http://repo1.maven.org/maven2/archetype-catalog.xml 通过eclipse下载和网页下载我这里都比较慢,最后用的迅雷下载 2.将本地xml文件配 ...
-
【swoole】结合swoole 和 nsq 的实际应用
集合 swoole 的框架设计 为了减少理解度,我尽量的从源头开始引入 1. nsq 案例中是使用 swoole 结合一个php 框架实现的是 NSQ 订阅功能. 启动命令: sudo bash /w ...
-
ASP.NET Core框架深度学习(四)宿主对象
11.WebHost 第六个对象 到目前为止我们已经知道了由一个服务器和多个中间件构成的管道是如何完整针对请求的监听.接收.处理和最终响应的,接下来来讨论这样的管道是如何被构建出来的.管道是在作为应 ...
-
HashMap、ConcurrentHashMap解析
一.HashMap分析 在JDK1.8之前,hashMap由数组+链表组成,1.8之后,对hashMap进行了一些修改,最大的不同就是利用了红黑树,所以其由数组+链表+红黑树组成.查找时,根据hash ...
-
LD_PRELOAD & putenv() 绕过 disable_functions & open_basedir
这次TCTF中一道题,给出了一个PHP一句话木马,设置了open_basedir,disable_functions包含所有执行系统命令的函数,然后目标是运行根目录下的/readflag,目标很明确, ...
-
顺F分享,你是在裸奔吗?
" 对顺F旗下各APP顺藤摸瓜分析--顺F分享." 前文对顺F速运和顺F速运国际版进行了分析,二者使用同一套接口,虽然保护强度不高,但对代码和数据的保护却区别对待,实在让人诧异. ...