文档章节

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

共有 人打赏支持
AllenOR灵感
粉丝 10
博文 2634
码字总数 82983
作品 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

没有更多内容

加载失败,请刷新页面

加载更多

下一页

nginx访问日志-日志切割-静态文件不记录日志和过期时间

nginx访问日志: vim /usr/local/nginx/conf/nginx.conf #搜索log_format 该字段定义日志格式,默认如下: #combined_realip日志格式的名字,可随意定义; 定义访问日志: 需在虚拟主机配置文...

ZHENG-JY
4分钟前
0
0
180.mariadb 主从复制

参考:https://blog.csdn.net/chengxuzaza/article/details/62042920 睡觉睡觉,明天写 1.效果 当主库中数据有变化的时候,从库就自动同步 2. 环境要求 至少两台 linux服务器 (教程:https...

Lucky_Me
14分钟前
0
0
erlng file id3v1 id3v1.1

%% ---%% Excerpted from "Programming Erlang",%% published by The Pragmatic Bookshelf.%% Copyrights apply to this code. It may not be used to create training material, %% ......

xueyuse0012
15分钟前
1
0
RabbitMq的安装

环境Centos6.5 32位 JDK 1.7.8 Jdk的卸载 rpm -qa|grep jdk yum –y remove 上边的安装包 JDK的安装 Rpm –ivh jdk安装包 配置环境变量 export JAVA_BIN=/usr/java/jdk1.7.0_80/bin export J......

DemonsI
19分钟前
0
0
http和https协议

HTTPS全称为Hypertext Transfer Protocol over Secure Socket Layer,中文含义为“超文本传输协议在安全加密字层”,简单来说就是加密数据传输,通俗的说就是安全连接。 HTTPS安全超文本传输...

寰宇01
25分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部