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编码问题
Mar 13 Python
python实现跨文件全局变量的方法
Jul 07 Python
python之wxPython菜单使用详解
Sep 28 Python
python实时分析日志的一个小脚本分享
May 07 Python
python中如何使用正则表达式的非贪婪模式示例
Oct 09 Python
Python之dict(或对象)与json之间的互相转化实例
Jun 05 Python
python3的输入方式及多组输入方法
Oct 17 Python
pycharm配置当鼠标悬停时快速提示方法参数
Jul 31 Python
Django为窗体加上防机器人的验证码功能过程解析
Aug 14 Python
Python实现栈的方法详解【基于数组和单链表两种方法】
Feb 22 Python
使用tensorflow框架在Colab上跑通猫狗识别代码
Apr 26 Python
python文件目录操作之os模块
May 08 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
Laravel使用模型实现like模糊查询的例子
2019/10/24 PHP
laravel框架中视图的基本使用方法分析
2019/11/23 PHP
JQuery 学习笔记 选择器之一
2009/07/23 Javascript
HTML Dom与Css控制方法
2010/10/25 Javascript
jQuery自动切换/点击切换选项卡效果的小例子
2013/08/12 Javascript
浅析Javascript中bind()方法的使用与实现
2016/04/29 Javascript
js制作可以延时消失的菜单
2017/01/13 Javascript
js return返回多个值,通过对象的属性访问方法
2017/02/21 Javascript
JavaScript校验Number(4,1)格式的数字实例代码
2017/03/13 Javascript
利用NPM淘宝的node.js镜像加速nvm
2017/03/27 Javascript
element上传组件循环引用及简单时间倒计时的实现
2018/10/01 Javascript
详解puppeteer使用代理
2018/12/27 Javascript
JS实现网页烟花动画效果
2020/03/10 Javascript
Vue 样式切换及三元判断样式关联操作
2020/08/09 Javascript
[01:12:27]EG vs Secret 2018国际邀请赛淘汰赛BO3 第二场 8.22
2018/08/23 DOTA
Python的Socket编程过程中实现UDP端口复用的实例分享
2016/03/19 Python
在Python程序和Flask框架中使用SQLAlchemy的教程
2016/06/06 Python
python3学生名片管理v2.0版
2018/11/29 Python
Python 实现子类获取父类的类成员方法
2019/01/11 Python
django的ORM操作 删除和编辑实现详解
2019/07/24 Python
logging level级别介绍
2020/02/21 Python
Python基础之列表常见操作经典实例详解
2020/02/26 Python
pycharm无法安装第三方库的问题及解决方法以scrapy为例(图解)
2020/05/09 Python
Python自动发送和收取邮件的方法
2020/08/12 Python
Lookfantastic挪威官网:英国知名美妆购物网站
2017/07/26 全球购物
Peter Millar官网:美国高档生活服饰品牌
2018/07/02 全球购物
澳大利亚珍珠首饰购物网站:Vayo Pearls
2019/03/11 全球购物
员工试用期考核自我鉴定
2014/04/13 职场文书
求职信名称怎么写
2014/05/26 职场文书
社区巾帼文明岗事迹材料
2014/06/03 职场文书
员工教育培训协议书
2014/09/27 职场文书
2015年留守儿童工作总结
2015/05/22 职场文书
2016年万圣节活动总结
2016/04/05 职场文书
Java 中的 Unsafe 魔法类的作用大全
2021/06/26 Java/Android
解决SpringBoot文件上传临时目录找不到的问题
2021/07/01 Java/Android
CSS3实现指纹特效代码
2022/03/17 HTML / CSS