文档章节

socket02客户端(封装)

AllenOR灵感
 AllenOR灵感
发布于 2017/09/10 01:17
字数 489
阅读 2
收藏 0

公共server代码

wrapper_socket/server.py

# -.- coding:utf-8 -.-
import socket

HOST = '127.0.0.1'
PORT = 50007
EOL1 = b'\r\n'
EOL2 = b'\r\n\r\n'

sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind((HOST, PORT))
sock.listen(1)

while True:
    try:
        data = b''
        connection, address = sock.accept()
        while True:
            data += connection.recv(4096)
            if EOL1 in data or EOL2 in data:
                break
        connection.sendall(data)
        connection.close()
    finally:
        connection.close()

 

独立的客户端

wrapper_socket/client.py

# -.- coding:utf-8 -.-
import sys
import socket

python_3 = sys.version_info >= (3,)

IDLE = 'idle'
CONN = 'connect'
SEND = 'send'


class TCPClient:

    _clients = {}

    def __init__(self, server_address,
                 family=socket.AF_INET,
                 _type=socket.SOCK_STREAM):

        self.server_address = server_address
        self.family = family
        self.type = _type
        self.sock = None
        self.__state = IDLE
        self._clients.update({id(self): self})
        self.connect()

    def __enter__(self):
        return self

    def __exit__(self, *exc_info):
        return self.exit()

    def _connect(self):
        self.__state = CONN
        if not all(self.remote_address()):
            self.sock = socket.socket(self.family, self.type)
        self.sock.connect(self.server_address)
        return self.sock

    def connect(self):
        # 判断是否与远程服务器建立连接.
        if self.sock is None:
            self._connect()
        else:
            self.reconnect()
        return self.sock

    def reconnect(self):
        self.close()
        return self._connect()

    def send(self, data):
        if self.__state == IDLE:
            self.connect()

        result = self._send(data)

        self.close()
        return result

    def _send(self, data):
        self.__state = SEND

        # python 3 环境下, 将 str 转换成 bytes
        if all([python_3, isinstance(data, str)]):
            data = bytes(data, encoding='utf-8')
        self.sock.sendall(data)

        return self.sock.recv(4096)

    def close(self):
        self.sock.close()
        self.sock = None
        self.__state = IDLE
        return self.sock

    def exit(self):
        if self.__state != IDLE:
            self.close()
        return self._clients.pop(id(self))

    def _address(self, side_address):
        try:
            pairs = getattr(self.sock, side_address)()
        except Exception:
            pairs = (None, None)
        return pairs

    def remote_address(self):
        return self._address('getpeername')

    def local_address(self):
        return self._address('getsockname')


class ConnectNotReady(Exception):
    pass


class SendNotReady(Exception):
    pass


if __name__ == '__main__':
    client = TCPClient(('127.0.0.1', 50007))
    print(client.send('hello world!\r\n\r\n'))
    print(client.send('hello world!\r\n\r\n'))
    print(client.send('hello world!\r\n\r\n'))
    client.exit()

    with TCPClient(server_address=('127.0.0.1', 50007)) as client:
        for i in range(3):
            print(client.send('use for iteration inner with\r\n\r\n'))

    for i in range(3):
        with TCPClient(server_address=('127.0.0.1', 50007)) as client:
            print(client.send('use for iteration\r\n\r\n'))

运行

# 启动服务 server.py
python wrapper_socket/server.py

# 运行客户端 client.py
python wrapper_socket/client.py

# 查看结果
b'hello world!\r\n\r\n'
b'hello world!\r\n\r\n'
b'hello world!\r\n\r\n'
b'use for iteration inner with\r\n\r\n'
b'use for iteration inner with\r\n\r\n'
b'use for iteration inner with\r\n\r\n'
b'use for iteration\r\n\r\n'
b'use for iteration\r\n\r\n'
b'use for iteration\r\n\r\n'

参考

本文转载自:http://www.jianshu.com/p/363969675897

共有 人打赏支持
上一篇: rust01安装
下一篇: redis03哈希
AllenOR灵感
粉丝 11
博文 2635
码字总数 83001
作品 0
程序员
私信 提问
Windows 2008下安装配置 WDS Windows部署服务-部署XP

接之前: http://mapengfei.blog.51cto.com/1552412/954075 上篇文章可以在企业中部署纯净版WIN7 ,但是实际上企业中有很多XP和在系统中预安装了许多软件,这就需要提前做好一台模板之后直接解封...

马鹏飞
2018/06/26
0
0
一次完整的HTTP请求处理过程

OSI七层模型我们都知道,那当我们从浏览器输入http://bbs.51cto.com/,到有页面显示的过程中发生了什么呢? 下面我们就通过抓包来分析: 网络传输 工具:任意浏览器、wireshark抓包工具 应用...

a_pan
2017/09/27
0
0
我理解的--java门面模式

这个模式只是简单方法的封装。把一些相关的方法提取出来,单独封装到一个类中。体现了框架的意义,把逻辑业务和客户端分开,更好的组织结构框架,很清晰明了。 门面重在客户端代码的简洁性。...

刘新全
2016/03/30
59
0
Redis 的 sharded jedis 客户端实现 - sparrow-sharded-jedis

通过对 Redis 客户端的封装,从代码级别强制规范 key,使 Redis 方便管理和监控。 理论上框架可实现跨各种缓存的 db 的缓存层,且安全,友好,调用简洁。 功能列表: 进一步对客户端友好封装...

zh_harry
2018/01/28
16
0
Spring Data Redis与Jedis的选择(转)

说明:内容可能有点旧,需要在业务上做权衡。 Redis的客户端有两种实现方式,一是可以直接调用Jedis来实现,二是可以使用Spring Data Redis,通过Spring的封装来调用。应该使用哪一个呢?基于...

easonjim
2017/11/08
0
0

没有更多内容

加载失败,请刷新页面

加载更多

tac 与cat

tac从后往前看文件,结合grep使用

writeademo
今天
2
0
表单中readonly和dsabled的区别

这两种写法都会使显示出来的文本框不能输入文字, 但disabled会使文本框变灰,而且通过通过表单提交时,获取不到文本框中的value值(如果有的话), 而readonly只是使文本框不能输入,外观没...

少年已不再年少
今天
2
0
SpringBoot上传图片操作

首先有个上传文件的工具类 /** * 文件上传 * @param file * @param filePath * @param fileName * @throws Exception */public static void uploadFile(byte[] file, String ...

_liucui_
今天
6
0
DrawerLayout

public class MainActivity extends BaseActivity implements NavigationView.OnNavigationItemSelectedListener,OnFragmentInteractionListener{ public NavigationView navView; ......

安卓工程师王恒
今天
2
0
python精简笔记

python精简笔记-字符串基本用法 字符串常见用法: * encode() # 编码成bytes类型 * find() # 查找子串 * index() # 获取下标 * replace() # 替换子串 * len(string) # 返回字符串长度,...

平头哥-Enjoystudy
今天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部