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实现博客文章爬虫示例
Feb 26 Python
Python 2.7.x 和 3.x 版本的重要区别小结
Nov 28 Python
使用Python装饰器在Django框架下去除冗余代码的教程
Apr 16 Python
python获取文件扩展名的方法
Jul 06 Python
Python编程实现微信企业号文本消息推送功能示例
Aug 21 Python
Django2.1集成xadmin管理后台所遇到的错误集锦(填坑)
Dec 20 Python
anaconda中更改python版本的方法步骤
Jul 14 Python
使用python实现画AR模型时序图
Nov 20 Python
基于python中__add__函数的用法
Nov 25 Python
Python字符串格式化常用手段及注意事项
Jun 17 Python
Python3使用tesserocr识别字母数字验证码的实现
Jan 29 Python
python绘制云雨图raincloud plot
Aug 05 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函数之error_reporting(E_ALL ^ E_NOTICE)详细说明
2011/07/01 PHP
用PHP提取中英文词语以及数字的首字母的方法介绍
2013/04/23 PHP
数组与类使用PHP的可变变量名需要的注意的问题
2013/06/20 PHP
PHP中防止SQL注入方法详解
2014/12/25 PHP
laravel框架模型中非静态方法也能静态调用的原理分析
2019/11/23 PHP
php判断IP地址是否在多个IP段内
2020/08/18 PHP
setTimeout和setInterval的区别你真的了解吗?
2011/03/31 Javascript
javascript根据像素点取位置示例
2014/01/27 Javascript
IE6浏览器中window.location.href无效的解决方法
2014/11/20 Javascript
jQuery实现彩带延伸效果的网页加载条loading动画
2015/10/29 Javascript
AngularJS实现textarea记录只能输入规定数量的字符并显示
2016/04/26 Javascript
AngularJS中directive指令使用之事件绑定与指令交互用法示例
2016/11/22 Javascript
浅谈JavaScript的闭包函数
2016/12/08 Javascript
javascript基本数据类型和转换
2017/03/17 Javascript
微信小程序实现带刻度尺滑块功能
2017/03/29 Javascript
微信小程序 自动登陆PHP源码实例(源码下载)
2017/05/08 Javascript
vue开发调试神器vue-devtools使用详解
2017/07/13 Javascript
Bootstrap Table 搜索框和查询功能
2017/11/30 Javascript
laravel实现中文和英语互相切换的例子
2019/09/30 Javascript
JavaScript中的相等操作符使用详解
2019/12/21 Javascript
JS数组reduce()方法原理及使用技巧解析
2020/07/14 Javascript
vue router-link 默认a标签去除下划线的实现
2020/11/06 Javascript
python写的ARP攻击代码实例
2014/06/04 Python
Python实现运行其他程序的四种方式实例分析
2017/08/17 Python
Python2与python3中 for 循环语句基础与实例分析
2017/11/20 Python
pandas表连接 索引上的合并方法
2018/06/08 Python
python日志logging模块使用方法分析
2019/05/23 Python
Python @property使用方法解析
2019/09/17 Python
tensorflow常用函数API介绍
2020/04/19 Python
浅谈Python中threading join和setDaemon用法及区别说明
2020/05/02 Python
html5的画布canvas——画出简单的矩形、三角形实例代码
2013/06/09 HTML / CSS
广州某公司软件工程师面试题
2014/12/22 面试题
社区包粽子活动方案
2014/01/21 职场文书
毕业生如何写自荐信
2014/03/26 职场文书
公司法定代表人授权委托书
2014/09/29 职场文书
团结主题班会
2015/08/13 职场文书