Python Socket编程Python Socket编程
时间:2022-05-14
本文章向大家介绍Python Socket编程Python Socket编程,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
Python Socket编程
在使用Python做socket编程时,由于需要使用阻塞(默认)的方式来读取数据流,此时对于数据的结束每次都需要自己处理,太麻烦。并且网上也没找到太好的封装,所以就自己写了个简单的封装。
封装思路
- 客户端每次请求均发送一个 SocketRequest 对象,其中封装具体的数据,这里使用json。对于要发送的数据,会自动添加一个结束符标识(EOF = '0x00')。
- 服务器端接收数据时,根据结束符标识来生成完整的数据,并解包成 SocketRequest 对象。
- 服务器端根据 SocketRequest 的内容,来生成 SocketResponse 对象,这里使用了一个 SimpleRequestHandler 类来处理,例子中就是没有做任何处理,然后原样返回。
- 服务器端发送 SocketResponse 给客户端。其中也需要对包做一个封装,会自动添加一个结束符标识(EOF = '0x00')。
- 客户接收数据时,根据结束符标识来生成完整的数据,并解包成 SocketResponse 对象,然后返回。
封装类
sockets.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import socket
import pickle
import thread
PORT = 12345
EOF = '0x00'
class SocketServer(object):
def __init__(self, port=None):
self.port = port
def startup(self):
sock_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock_server.bind(('0.0.0.0', self.port))
sock_server.listen(0)
while True:
sock, address = sock_server.accept()
thread.start_new_thread(self.__invoke, (sock, address))
def shutdown(self):
pass
def __invoke(self, sock, address):
try:
full_data = ''
while True:
data = sock.recv(1024)
if data is None:
return
full_data += data
if full_data.endswith(EOF):
full_data = full_data[0:len(full_data) - len(EOF)]
request = pickle.loads(full_data)
response = SimpleRequestHandler().handle(request)
sock.sendall(pickle.dumps(response) + EOF)
return
except Exception as e:
print e
finally:
sock.close()
class SocketClient(object):
def __init__(self, host, port):
self.host = host
self.port = port
def execute(self, request):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((self.host, self.port))
try:
sock.sendall(pickle.dumps(request) + EOF)
full_data = ''
while True:
data = sock.recv(1024)
if data:
full_data += data
if full_data.endswith(EOF):
full_data = full_data[0:len(full_data) - len(EOF)]
response = pickle.loads(full_data)
return response
else:
return None
except Exception as e:
print e
return None
finally:
sock.close()
class SocketRequest(object):
def __init__(self, data):
self.data = data
def __repr__(self):
return repr(self.__dict__)
class SocketResponse(object):
def __init__(self, data):
self.data = data
def __repr__(self):
return repr(self.__dict__)
class SimpleRequestHandler(object):
def __init__(self):
pass
def __repr__(self):
return repr(self.__dict__)
def handle(self, request):
return SocketResponse(request.data)
测试
socket_server.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from agent.sockets import *
ss = SocketServer(PORT)
ss.startup()
socket_client.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import pickle
from agent.sockets import *
sc = SocketClient('localhost', PORT)
request = SocketRequest('abc')
response = sc.execute(request)
print request
print response
运行测试
首先,运行 socket_server.py
然后,运行 socket_client.py
- Golang 基本语法学习笔记之流程控制
- Go 语言的演化历程
- JS 评分五角星随鼠标移动显示
- Golang标准库学习——buffio包 ---转
- 【Go 语言社区】Go语言条件变量的两个例子
- mysqlimport导入报错的排查(r10笔记第58天)
- 【Go 语言社区】POJ 1047 Round and Round We Go 循环数新解
- 【Go 语言社区】删除redis所有KEY
- 【Go 语言社区】Golang 动态实例化结构体
- 【Go 语言社区】Go 错误处理
- 【Go 语言社区】Go 语言范围(Range)
- 【Go 语言社区】JS 相关---Window Location
- 【Go 语言社区】Go 语言Map(集合)
- 【Go 语言社区】JavaScript Date(日期)对象
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- c/c++补完计划(五): 平衡二叉树和二叉搜索树
- 【原创】Java并发编程系列30 | ThreadLocal
- c/c++补完计划(六): 语法糖lambda
- 从别人的代码中学习golang系列--03
- Flink写出数据到HBase的Sink实现
- 「MoreThanJava」Day 4:面向对象基础
- RTSP协议视频平台EasyNVR接入EasyNVS通道不显示任何数据怎么处理?
- RTSP协议视频平台EasyNVR接入视频综合管理平台EasyNVS可以自由修改配置吗?
- 使用Azure人脸API对图片进行人脸识别
- 视频综合管理平台EasyNVS显示的rtsp和rtmp穿透地址错误如何解决?
- 开发RTSP协议视频平台EasyNVR采用ffmpeg集成fdk-aac报no member named “encoderDelay”
- 微信小程序开发实战(17):用画布画一张笑脸
- PHP中Session ID的实现原理分析和实例解析
- 【好文推荐】黑莓OS手册是如何详细阐述底层的进程和线程模型的?
- 简析Spark Streaming/Flink的Kafka动态感知