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 08 Python
基于Python实现的百度贴吧网络爬虫实例
Apr 17 Python
Python搭建APNS苹果推送通知推送服务的相关模块使用指南
Jun 02 Python
pycharm远程调试openstack的图文教程
Nov 21 Python
在windows下Python打印彩色字体的方法
May 15 Python
python多进程控制学习小结
Oct 31 Python
详解Django+Uwsgi+Nginx 实现生产环境部署
Nov 06 Python
pyqt实现.ui文件批量转换为对应.py文件脚本
Jun 19 Python
tensorflow模型的save与restore,及checkpoint中读取变量方式
May 26 Python
在Keras中CNN联合LSTM进行分类实例
Jun 29 Python
一文读懂python Scrapy爬虫框架
Feb 24 Python
使用pandas读取表格数据并进行单行数据拼接的详细教程
Mar 03 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
中国收音机工业发展史
2021/03/02 无线电
PHP 模板高级篇总结
2006/12/21 PHP
php入门学习知识点六 PHP文件的读写操作代码
2011/07/14 PHP
windows下zendframework项目环境搭建(通过命令行配置)
2012/12/06 PHP
php中的抽象方法和抽象类
2017/02/14 PHP
使用laravel的migrate创建数据表的方法
2019/09/30 PHP
关于取不到由location.href提交而来的上级页面地址的解决办法
2009/07/30 Javascript
JavaScript类库D
2010/10/24 Javascript
javascript面向对象包装类Class封装类库剖析
2013/01/24 Javascript
javascript操作css属性
2013/12/30 Javascript
JS根据变量保存方法名并执行方法示例
2014/04/04 Javascript
jQuery插件zepto.js简单实现tab切换
2015/06/16 Javascript
JS中取二维数组中最大值的方法汇总
2016/04/17 Javascript
Javascript数组循环遍历之forEach详解
2016/11/07 Javascript
如何检查一个对象是否为空
2019/04/11 Javascript
JavaScript中变量提升机制示例详解
2019/12/27 Javascript
[13:40]TI3青蛙君全程回顾 DOTA2我们为梦想再战
2013/09/13 DOTA
浅谈Python中copy()方法的使用
2015/05/21 Python
Python中struct模块对字节流/二进制流的操作教程
2017/01/21 Python
python smtplib模块自动收发邮件功能(一)
2018/05/22 Python
python实现BP神经网络回归预测模型
2019/08/09 Python
python画环形图的方法
2020/03/25 Python
使用keras实现Precise, Recall, F1-socre方式
2020/06/15 Python
什么是servlet
2012/05/08 面试题
《伯牙绝弦》教学反思
2014/03/02 职场文书
2014庆六一活动方案
2014/03/02 职场文书
篝火晚会主持词
2014/03/25 职场文书
食堂标语大全
2014/06/11 职场文书
2014党委书记四风对照检查材料思想汇报
2014/09/21 职场文书
领导班子党的群众路线教育实践活动对照检查材料
2014/09/25 职场文书
离婚协议书范本2014
2014/10/27 职场文书
如何写贫困证明申请书
2014/10/29 职场文书
党支部工作总结2015
2015/04/01 职场文书
因工资原因离职的辞职信范文
2015/05/12 职场文书
表彰大会新闻稿
2015/07/17 职场文书
HTML5 新增内容和 API详解
2021/11/17 HTML / CSS