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获取CPU和内存信息的思路与实现(linux系统)
Jan 03 Python
利用Pandas 创建空的DataFrame方法
Apr 08 Python
Python 实现删除某路径下文件及文件夹的实例讲解
Apr 24 Python
对Python 内建函数和保留字详解
Oct 15 Python
使用Python的toolz库开始函数式编程的方法
Nov 15 Python
Python 获取主机ip与hostname的方法
Dec 17 Python
Django中使用haystack+whoosh实现搜索功能
Oct 08 Python
python json 递归打印所有json子节点信息的例子
Feb 27 Python
Python运行异常管理解决方案
Mar 09 Python
Python如何操作docker redis过程解析
Aug 10 Python
Pycharm常用快捷键总结及配置方法
Nov 14 Python
Python实现生活常识解答机器人
Jun 28 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数据流应用的一个简单实例
2012/09/14 PHP
php数组去除空值函数分享
2015/02/02 PHP
PHP实现登陆并抓取微信列表中最新一组微信消息的方法
2017/07/10 PHP
IE6下focus与blur错乱的解决方案
2011/07/31 Javascript
javascript模版引擎-tmpl的bug修复与性能优化分析
2011/10/23 Javascript
JS修改css样式style浅谈
2013/05/06 Javascript
浅析onsubmit校验表单时利用ajax的return false无效问题
2013/07/10 Javascript
js中substr,substring,indexOf,lastIndexOf的用法小结
2013/12/27 Javascript
JavaScript实现俄罗斯方块游戏过程分析及源码分享
2015/03/23 Javascript
js简单设置与使用cookie的方法
2016/01/22 Javascript
Angular.js回顾ng-app和ng-model使用技巧
2016/04/26 Javascript
学JavaScript七大注意事项【必看】
2016/05/04 Javascript
Bootstrap 源代码分析(未完待续)
2016/08/17 Javascript
pace.js和NProgress.js两个加载进度插件的一点小总结
2018/01/31 Javascript
jQuery基于闭包实现的显示与隐藏div功能示例
2018/06/09 jQuery
jQuery+Datatables实现表格批量删除功能【推荐】
2018/10/24 jQuery
vue中如何实现后台管理系统的权限控制的方法步骤
2019/09/05 Javascript
使用JavaScript获取扫码枪扫描得到的条形码的思路代码详解
2020/06/10 Javascript
vue+springboot+element+vue-resource实现文件上传教程
2020/10/21 Javascript
Python3学习笔记之列表方法示例详解
2017/10/06 Python
Python函数返回不定数量的值方法
2019/01/22 Python
Python中常用的内置方法
2019/01/28 Python
浅谈Python大神都是这样处理XML文件的
2019/05/31 Python
django model object序列化实例
2020/03/13 Python
使用python批量转换文件编码为UTF-8的实现
2020/04/03 Python
python输出结果刷新及进度条的实现操作
2020/07/13 Python
PyCharm Ctrl+Shift+F 失灵的简单有效解决操作
2021/01/15 Python
用gpu训练好的神经网络,用tensorflow-cpu跑出错的原因及解决方案
2021/03/03 Python
Nixon手表英国官网:美国尼克松手表品牌
2020/02/10 全球购物
学生会竞选自荐信
2013/10/12 职场文书
员工评语大全
2014/01/19 职场文书
美容院管理规章制度
2015/08/05 职场文书
PhpSpreadsheet中文文档 | Spreadsheet操作教程实例
2021/04/01 PHP
为什么在foreach循环中JAVA集合不能添加或删除元素
2021/06/11 Java/Android
Python获取江苏疫情实时数据及爬虫分析
2021/08/02 Python
Mysql 如何合理地统计一个数据库里的所有表的数据量
2022/04/18 MySQL