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 相关文章推荐
python3使用PyMysql连接mysql数据库实例
Feb 07 Python
django模板语法学习之include示例详解
Dec 17 Python
Python2.X/Python3.X中urllib库区别讲解
Dec 19 Python
python监控键盘输入实例代码
Feb 09 Python
Python 调用PIL库失败的解决方法
Jan 08 Python
在Python中将函数作为另一个函数的参数传入并调用的方法
Jan 22 Python
解决python3中的requests解析中文页面出现乱码问题
Apr 19 Python
Django之使用内置函数和celery发邮件的方法示例
Sep 16 Python
Pytorch在NLP中的简单应用详解
Jan 08 Python
在python中logger setlevel没有生效的解决
Feb 21 Python
从python读取sql的实例方法
Jul 21 Python
Python常用数字处理基本操作汇总
Sep 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
雄兵连:天使彦天使彦为爱折翼,彦和炙心同时念动的誓言!
2020/03/02 国漫
帅气的琦玉老师
2020/03/02 日漫
PHP的FTP学习(一)[转自奥索]
2006/10/09 PHP
destoon实现商铺管理主页设置增加新菜单的方法
2014/06/26 PHP
PHP curl使用实例
2015/07/02 PHP
PHP程序员的技术成长规划
2016/03/25 PHP
PHP获取HTTP body内容的方法
2018/12/31 PHP
php并发加锁问题分析与设计代码实例讲解
2021/02/26 PHP
宝塔面板在NGINX环境中TP5.1如何运行?
2021/03/09 PHP
前端开发必须知道的JS之原型和继承
2010/07/06 Javascript
改进版通过Json对象实现深复制的方法
2012/10/24 Javascript
js实现点击链接后窗口缩小并居中的方法
2015/03/02 Javascript
AngularJs表单验证实例代码解析
2016/11/29 Javascript
angularJS利用ng-repeat遍历二维数组的实例代码
2017/06/03 Javascript
nodejs连接mysql数据库及基本知识点详解
2018/03/20 NodeJs
Vue中使用webpack别名的方法实例详解
2018/06/19 Javascript
详解微信小程序的 request 封装示例
2018/08/21 Javascript
Vue中的methods、watch、computed的区别
2018/11/26 Javascript
通过js实现压缩图片上传功能
2020/02/25 Javascript
Javascript中Math.max和Math.max.apply的区别和用法详解
2020/08/24 Javascript
使用python脚本实现查询火车票工具
2018/07/19 Python
解决Mac下首次安装pycharm无project interpreter的问题
2018/10/29 Python
Python爬取爱奇艺电影信息代码实例
2019/11/26 Python
Python爬虫之Spider类用法简单介绍
2020/08/04 Python
如何使用scrapy中的ItemLoader提取数据
2020/09/30 Python
python中openpyxl和xlsxwriter对Excel的操作方法
2021/03/01 Python
matplotlib阶梯图的实现(step())
2021/03/02 Python
实习护理工作自我评价
2013/09/25 职场文书
大学运动会入场词
2014/02/22 职场文书
物资采购方案
2014/06/12 职场文书
房屋租赁授权委托书范本
2014/09/20 职场文书
房屋产权证明书
2015/06/19 职场文书
深入理解python多线程编程
2021/04/18 Python
Python闭包的定义和使用方法
2022/04/11 Python
Vue组件化(ref,props, mixin,.插件)详解
2022/05/15 Vue.js
Redis批量生成数据的实现
2022/06/05 Redis