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使用win32com在百度空间插入html元素示例
Feb 20 Python
使用Python的Scrapy框架编写web爬虫的简单示例
Apr 17 Python
一个基于flask的web应用诞生(1)
Apr 11 Python
Python 实现异步调用函数的示例讲解
Oct 14 Python
python 递归深度优先搜索与广度优先搜索算法模拟实现
Oct 22 Python
通过python实现弹窗广告拦截过程详解
Jul 10 Python
django 信号调度机制详解
Jul 19 Python
Python3并发写文件与Python对比
Nov 20 Python
pytorch dataloader 取batch_size时候出现bug的解决方式
Feb 20 Python
python函数调用,循环,列表复制实例
May 03 Python
Python requests上传文件实现步骤
Sep 15 Python
matplotlib对象拾取事件处理的实现
Jan 14 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+mysql开源XNA 聚合程序发布 下载
2007/07/13 PHP
深入php define()函数以及defined()函数的用法详解
2013/06/05 PHP
php 修改、增加xml结点属性的实现代码
2013/10/22 PHP
php二维数组排序详解
2013/11/06 PHP
php数组索引与键值操作技巧实例分析
2015/06/24 PHP
服务器安全设置的几个注册表设置
2007/07/28 Javascript
JS创建优美的页面滑动块效果 - Glider.js
2007/09/27 Javascript
jQuery Tools tab使用介绍
2012/07/14 Javascript
js indexOf()定义和用法
2012/10/21 Javascript
js 中将多个逗号替换为一个逗号的代码
2014/06/07 Javascript
jQuery实现的导航条切换可显示隐藏
2014/10/22 Javascript
js实现鼠标经过表格行变色的方法
2015/05/12 Javascript
基于JavaScript实现鼠标箭头移动图片跟着移动
2016/08/30 Javascript
利用Vue.js实现求职在线之职位查询功能
2017/07/03 Javascript
详解angular2.x创建项目入门指令
2018/10/11 Javascript
微信小程序自定义单项选择器样式
2019/07/25 Javascript
JS实现星星海特效
2019/12/24 Javascript
jQuery实现放大镜案例
2020/10/19 jQuery
[01:57]2018年度DOTA2最具潜力解说-完美盛典
2018/12/16 DOTA
详解Python中for循环的使用方法
2015/05/14 Python
Django中的CACHE_BACKEND参数和站点级Cache设置
2015/07/23 Python
python版本坑:md5例子(python2与python3中md5区别)
2017/06/20 Python
Python数据可视化编程通过Matplotlib创建散点图代码示例
2017/12/09 Python
python爬虫之urllib3的使用示例
2018/07/09 Python
转换科学计数法的数值字符串为decimal类型的方法
2018/07/16 Python
Django 创建/删除用户的示例代码
2019/07/24 Python
Python3多线程版TCP端口扫描器
2019/08/31 Python
Python线程协作threading.Condition实现过程解析
2020/03/12 Python
python框架flask入门之环境搭建及开启调试
2020/06/07 Python
Python用requests库爬取返回为空的解决办法
2021/02/21 Python
详解html5 canvas 微信海报分享(个人爬坑)
2018/01/12 HTML / CSS
linux面试题参考答案(7)
2012/10/29 面试题
Linux的文件类型
2016/07/05 面试题
离职感谢信怎么写
2015/01/22 职场文书
创业计划书之寿司
2019/07/19 职场文书
详解Flutter自定义应用程序内键盘的实现方法
2022/06/14 Java/Android