Python Socket编程详细介绍


Posted in Python onMarch 23, 2017

在使用Python做socket编程时,由于需要使用阻塞(默认)的方式来读取数据流,此时对于数据的结束每次都需要自己处理,太麻烦。并且网上也没找到太好的封装,所以就自己写了个简单的封装。

封装思路

1. 客户端每次请求均发送一个 SocketRequest 对象,其中封装具体的数据,这里使用json。对于要发送的数据,会自动添加一个结束符标识(EOF = ‘0x00')。

2. 服务器端接收数据时,根据结束符标识来生成完整的数据,并解包成 SocketRequest 对象。

3. 服务器端根据 SocketRequest 的内容,来生成 SocketResponse 对象,这里使用了一个 SimpleRequestHandler 类来处理,例子中就是没有做任何处理,然后原样返回。

4. 服务器端发送 SocketResponse 给客户端。其中也需要对包做一个封装,会自动添加一个结束符标识(EOF = ‘0x00')。

5. 客户接收数据时,根据结束符标识来生成完整的数据,并解包成 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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python显示进度条的方法
Sep 20 Python
Python 文件管理实例详解
Nov 10 Python
Python 中开发pattern的string模板(template) 实例详解
Apr 01 Python
学习python中matplotlib绘图设置坐标轴刻度、文本
Feb 07 Python
Python Numpy计算各类距离的方法
Jul 05 Python
python selenium 查找隐藏元素 自动播放视频功能
Jul 24 Python
Python爬虫 bilibili视频弹幕提取过程详解
Jul 31 Python
python opencv将表格图片按照表格框线分割和识别
Oct 30 Python
pytorch中tensor张量数据类型的转化方式
Dec 31 Python
python爬虫beautifulsoup解析html方法
Dec 07 Python
彻底解决pip下载pytorch慢的问题方法
Mar 01 Python
深入理解pytorch库的dockerfile
Jun 10 Python
python3中int(整型)的使用教程
Mar 23 #Python
python利用Guetzli批量压缩图片
Mar 23 #Python
python3中str(字符串)的使用教程
Mar 23 #Python
python常用知识梳理(必看篇)
Mar 23 #Python
Python爬取qq music中的音乐url及批量下载
Mar 23 #Python
Python爬取网页中的图片(搜狗图片)详解
Mar 23 #Python
Python编程之event对象的用法实例分析
Mar 23 #Python
You might like
PHP中soap的用法实例
2014/10/24 PHP
ThinkPHP中redirect用法分析
2014/12/05 PHP
PHP下载生成的csv文件及问题总结
2015/08/06 PHP
Laravel框架实现的rbac权限管理操作示例
2019/01/16 PHP
在jQuery ajax中按钮button和submit的区别分析
2012/10/07 Javascript
JS与C#编码解码
2013/12/03 Javascript
jQuery中height()方法用法实例
2014/12/24 Javascript
Jquery判断form表单数据是否变化
2016/03/30 Javascript
js获取当前年月日-YYYYmmDD格式的实现代码
2016/06/01 Javascript
常用js,css文件统一加载方法(推荐) 并在加载之后调用回调函数
2016/09/23 Javascript
jquery删除数组中重复元素
2016/12/05 Javascript
VueJs 搭建Axios接口请求工具
2017/11/20 Javascript
在Angular中使用JWT认证方法示例
2018/09/10 Javascript
webpack dll打包重复问题优化的解决
2018/10/10 Javascript
Element-UI踩坑之Pagination组件的使用
2018/10/29 Javascript
我要点爆”微信小程序云开发之项目建立与我的页面功能实现
2019/05/26 Javascript
Python iter()函数用法实例分析
2018/03/17 Python
python 爬虫 批量获取代理ip的实例代码
2018/05/22 Python
对django中render()与render_to_response()的区别详解
2018/10/16 Python
PyTorch 1.0 正式版已经发布了
2018/12/13 Python
在numpy矩阵中令小于0的元素改为0的实例
2019/01/26 Python
详解字符串在Python内部是如何省内存的
2020/02/03 Python
HTML5全屏(Fullscreen)API详细介绍
2015/04/24 HTML / CSS
C#如何调用Windows程序打开一个文档
2014/12/26 面试题
会计找工作求职信范文
2013/12/09 职场文书
幼儿园毕业家长感言
2014/02/10 职场文书
讲文明树新风公益广告宣传方案
2014/02/25 职场文书
文明和谐家庭事迹材料
2014/05/18 职场文书
社区精神文明建设汇报材料
2014/08/17 职场文书
幼儿园老师新年寄语2015
2014/12/08 职场文书
2016年禁毒宣传活动总结
2016/04/05 职场文书
MySQL 覆盖索引的优点
2021/05/19 MySQL
Python办公自动化PPT批量转换操作
2021/09/15 Python
Python 键盘事件详解
2021/11/11 Python
SQL SERVER中的流程控制语句
2022/05/25 SQL Server
使用Cargo工具高效创建Rust项目
2022/08/14 Javascript