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发送邮件实例讲解(python发邮件附件可以使用email模块实现)
Dec 03 Python
python实现网页链接提取的方法分享
Feb 25 Python
Python实现数据库并行读取和写入实例
Jun 09 Python
Python中join函数简单代码示例
Jan 09 Python
python DataFrame 修改列的顺序实例
Apr 10 Python
解决Pytorch 训练与测试时爆显存(out of memory)的问题
Aug 20 Python
python实现井字棋小游戏
Mar 04 Python
PYQT5 vscode联合操作qtdesigner的方法
Mar 24 Python
keras 使用Lambda 快速新建层 添加多个参数操作
Jun 10 Python
django filter过滤器实现显示某个类型指定字段不同值方式
Jul 16 Python
详解numpy1.19.4与python3.9版本冲突解决
Dec 15 Python
Matplotlib animation模块实现动态图
Feb 25 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
层叠菜单的动态生成
2006/10/09 PHP
PHP判断图片格式的七种方法小结
2013/06/03 PHP
PHP Session机制简介及用法
2014/08/19 PHP
php恢复数组的key为数字序列的方法
2015/04/28 PHP
PHP连接MYSQL数据库实例代码
2016/01/20 PHP
php基于curl实现的股票信息查询类实例
2016/11/11 PHP
PHP+Mysql+Ajax实现淘宝客服或阿里旺旺聊天功能(前台页面)
2017/06/16 PHP
PHP上传图片到数据库并显示的实例代码
2019/12/20 PHP
用javascript实现页面打印的三种方法
2007/03/05 Javascript
Discuz! 6.1_jQuery兼容问题
2008/09/23 Javascript
js 页面传参数时 参数值含特殊字符的问题
2009/12/13 Javascript
提升你网站水平的jQuery插件集合推荐
2011/04/19 Javascript
Js 冒泡事件阻止实现代码
2013/01/27 Javascript
JavaScript自执行闭包的小例子
2013/06/29 Javascript
JS实现可关闭的对联广告效果代码
2015/09/14 Javascript
基于jQuery和Bootstrap框架实现仿知乎前端动态列表效果
2016/11/09 Javascript
解析如何利用iframe标签以及js制作时钟
2016/12/08 Javascript
史上最全JavaScript常用的简写技巧(推荐)
2017/08/17 Javascript
深入理解Vue生命周期、手动挂载及挂载子组件
2017/09/27 Javascript
vue jsx 使用指南及vue.js 使用jsx语法的方法
2017/11/11 Javascript
python选择排序算法的实现代码
2013/11/21 Python
从零学python系列之教你如何根据图片生成字符画
2014/05/23 Python
Python实现Linux的find命令实例分享
2017/06/04 Python
Python数据结构与算法之图结构(Graph)实例分析
2017/09/05 Python
基于Python实现签到脚本过程解析
2019/10/25 Python
Python获取、格式化当前时间日期的方法
2020/02/10 Python
如何清空python的变量
2020/07/05 Python
Python使用内置函数setattr设置对象的属性值
2020/10/16 Python
用Java语言将一个键盘输入的数字转化成中文输出
2013/01/25 面试题
汽车专业毕业生自荐信
2013/11/03 职场文书
人力资源管理专业毕业生推荐信
2013/11/07 职场文书
医学专业应届生的自我评价
2014/02/28 职场文书
电话营销开场白
2015/05/29 职场文书
MySQL的join buffer原理
2021/04/29 MySQL
html+css实现环绕倒影加载特效
2021/07/07 HTML / CSS
IDEA 2022 Translation 未知错误 翻译文档失败
2022/04/24 Java/Android