文档章节

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灵感
粉丝 10
博文 2635
码字总数 83001
作品 0
程序员
私信 提问
Windows 2008下安装配置 WDS Windows部署服务-部署XP

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

马鹏飞
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
01/28
16
0
Java Socket的封装

摘要: Socket通信几乎无时不在, 当然能够搜集到的信息也大量存在, 为了避免重复的劳作, 抽取了关于客户端和服务端的Socket, 并将其应用到适合JVM(LInux/Windows)或者DVM(Android)平台. 这个封...

晨曦之光
2012/03/09
2.9K
0

没有更多内容

加载失败,请刷新页面

加载更多

Vue重要知识小结

vue sync修饰 (1)双向数据绑定,父子组件之间信息的交互 1⃣️在自组件中使用this.emmit('toFather'),子组件产生一个tofather事件,然后在父组件中通过@进行监听,那么可以实现通信过程 2⃣...

peakedness丶
36分钟前
1
0
1024我们的码农节-向自己致敬!

一、blog主有话要说 作为(真正)入赘程序届的第一年, 对明天的1024码农节有很多话想说.比如: 给各位辛苦大佬们讲几个咱们程序届段子 给自己立一个flag, 明年的1024争取少掉点甚至不掉头发! ...

Ala6
38分钟前
10
0
solr使用规范

0. 目的 规范solr设计、用法,避免bug,提高性能 1. 设计规范 solr的用途是查询,不是存储,建议查询结果尽量都为id主键,而后再拿该id主键到缓存或者db中再查询相关信息,例如:请勿将经销商...

andersChow
50分钟前
1
0
11-《深度拆解JVM》之Java对象的内存布局

一、问题引入 在 Java 程序中,我们拥有多种新建对象的方式。除了最为常见的 new 语句之外,我们还可以通过反射机制、Object.clone 方法、反序列化以及 Unsafe.allocateInstance 方法来新建对...

飞鱼说编程
55分钟前
1
0
Windows Install Docker

win7、win8 win7、win8 等需要利用 docker toolbox 来安装,国内可以使用阿里云的镜像来下载,下载地址:http://mirrors.aliyun.com/docker-toolbox/windows/docker-toolbox/ docker toolbox...

linuxprobe16
59分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部