Python Socket编程中基于结束符的简单封装实现

小鹿同学
小鹿同学
发布时间:2026-10-13 | 2人浏览过
原创

本文介绍了一种Python Socket编程的简单封装方案,旨在解决默认阻塞读取数据流时处理数据结束的复杂性。通过自定义SocketRequest和SocketResponse类,利用EOF标识符自动处理数据包的完整性和解包,实现了客户端与服务端之间高效、简洁的数据交互机制。

在进行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 相关产品和应用

全部下载

专题列表