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连接sql server乱码的解决方法
Jan 28 Python
Python中的rfind()方法使用详解
May 19 Python
Python编程pygame模块实现移动的小车示例代码
Jan 03 Python
解决pandas 作图无法显示中文的问题
May 24 Python
Python实现string字符串连接的方法总结【8种方式】
Jul 06 Python
python实现换位加密算法的示例
Oct 14 Python
Python中出现IndentationError:unindent does not match any outer indentation level错误的解决方法
Apr 18 Python
python3正则模块re的使用方法详解
Feb 11 Python
Python 实现向word(docx)中输出
Feb 13 Python
django 取消csrf限制的实例
Mar 13 Python
python中pow函数用法及功能说明
Dec 04 Python
Python爬虫后获取重定向url的两种方法
Jan 19 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
Dedecms常用函数解析
2008/02/01 PHP
php小偷相关截取函数备忘
2010/11/28 PHP
利用curl 多线程 模拟 并发的详解
2013/06/14 PHP
PHP仿博客园 个人博客(1) 数据库与界面设计
2013/07/05 PHP
PHP中的多行字符串传递给JavaScript的两种方法
2014/06/19 PHP
ThinkPHP3.1的Widget新用法
2014/06/19 PHP
浅析PHP程序设计中的MVC编程思想
2014/07/28 PHP
php中substr()函数参数说明及用法实例
2014/11/15 PHP
PHP CURL采集百度搜寻结果图片不显示问题的解决方法
2017/02/03 PHP
微信支付之JSAPI公众号支付详解
2019/05/15 PHP
Laravel 将数据表的数据导出,并生成seeds种子文件的方法
2019/10/09 PHP
php 使用expat方式解析xml文件操作示例
2019/11/26 PHP
Node调试工具JSHint的安装及配置教程
2014/05/27 Javascript
js实现从数组里随机获取元素
2015/01/12 Javascript
JavaScript使用Max函数返回两个数字中较大数的方法
2015/04/06 Javascript
JS实现新浪博客左侧的Blog管理菜单效果代码
2015/10/22 Javascript
浅析JS动态创建元素【两种方法】
2016/04/20 Javascript
关于数据与后端进行交流匹配(点亮星星)
2016/08/03 Javascript
JS 事件绑定、事件监听、事件委托详细介绍
2016/09/28 Javascript
纯js实现悬浮按钮组件
2016/12/17 Javascript
JavaScript中import用法总结
2019/01/20 Javascript
原生js实现抽奖小游戏
2019/06/27 Javascript
NUXT SSR初级入门笔记(小结)
2019/12/16 Javascript
适用于 Vue 的播放器组件Vue-Video-Player操作
2020/11/16 Javascript
浅谈Python中数据解析
2015/05/05 Python
Python 列表(List) 的三种遍历方法实例 详解
2017/04/15 Python
python 3.3 下载固定链接文件并保存的方法
2018/12/18 Python
python字符串替换第一个字符串的方法
2019/06/26 Python
利用纯html5绘制出来的一款非常漂亮的时钟
2015/01/04 HTML / CSS
义务教育学校标准化建设汇报材料
2014/08/16 职场文书
党员专题组织生活会发言材料
2014/10/17 职场文书
高三语文复习计划
2015/01/19 职场文书
兴趣班停课通知
2015/04/24 职场文书
幼儿园六一主持词
2015/06/30 职场文书
火锅店的开业营销方案范本!
2019/07/05 职场文书
Python 键盘事件详解
2021/11/11 Python