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中的探索性数据分析(功能式)
Dec 22 Python
python快速建立超简单的web服务器的实现方法
Feb 17 Python
Sanic框架异常处理与中间件操作实例分析
Jul 16 Python
Python给图像添加噪声具体操作
Mar 03 Python
详解Python读取yaml文件多层菜单
Mar 23 Python
numpy linalg模块的具体使用方法
May 26 Python
Python多叉树的构造及取出节点数据(treelib)的方法
Aug 09 Python
基于keras中的回调函数用法说明
Jun 17 Python
Python代码注释规范代码实例解析
Aug 14 Python
Python 排序最长英文单词链(列表中前一个单词末字母是下一个单词的首字母)
Dec 14 Python
Python实现随机爬山算法
Jan 29 Python
Python创建自己的加密货币的示例
Mar 01 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中随机函数mt_rand()与rand()性能对比分析
2014/12/01 PHP
PHP中$GLOBALS与global的区别详解
2019/03/21 PHP
学习YUI.Ext第五日--做拖放Darg&Drop
2007/03/10 Javascript
Js 时间函数getYear()的使用问题探讨
2013/04/01 Javascript
单击浏览器右上角的X关闭窗口弹出提示的小例子
2013/06/12 Javascript
分享20个提升网站界面体验的jQuery插件
2014/12/15 Javascript
Javascript核心读书有感之类型、值和变量
2015/02/11 Javascript
Jquery修改image的src属性,图片不加载问题的解决方法
2016/05/17 Javascript
js不间断滚动的简单实现
2016/06/03 Javascript
javascript之Boolean类型对象
2016/06/07 Javascript
JS Ajax请求如何防止重复提交
2016/06/13 Javascript
jQuery居中元素scrollleft计算方法示例
2017/01/16 Javascript
JavaScript中for循环的几种写法与效率总结
2017/02/03 Javascript
jQuery Mobile漏洞会有跨站脚本攻击风险
2017/02/12 Javascript
WebPack配置vue多页面的技巧
2018/05/15 Javascript
vue组件jsx语法的具体使用
2018/05/21 Javascript
antd组件Upload实现自己上传的实现示例
2018/12/18 Javascript
Vue中UI组件库之Vuex与虚拟服务器初识
2019/05/07 Javascript
vue组件三大核心概念图文详解
2019/05/30 Javascript
使用layer.msg 时间设置不起作用的解决方法
2019/09/12 Javascript
解决axios post 后端无法接收数据的问题
2019/10/29 Javascript
vue quill editor 使用富文本添加上传音频功能
2020/01/14 Javascript
jquery实现抽奖功能
2020/10/22 jQuery
[01:29]Ti4循环赛第三日精彩回顾
2014/07/13 DOTA
python实现简单加密解密机制
2019/03/19 Python
python自动化测试之如何解析excel文件
2019/06/27 Python
numpy ndarray 按条件筛选数组,关联筛选的例子
2019/11/26 Python
基于python实现简单C/S模式代码实例
2020/09/14 Python
Python爬取微信小程序Charles实现过程图解
2020/09/29 Python
请写出 float x 与"零值"比较的 if 语句
2016/01/04 面试题
电大毕业自我鉴定
2014/02/03 职场文书
党的群众路线教育实践活动个人对照检查材料(公安)
2014/11/05 职场文书
高考学习决心书
2015/02/04 职场文书
幼儿园食品安全责任书
2015/05/08 职场文书
Go 在 MongoDB 中常用查询与修改的操作
2021/05/07 Golang
Python实现Excel文件的合并(以新冠疫情数据为例)
2022/03/20 Python