socket02客户端(封装)
socket02客户端(封装)
AllenOR灵感 发表于6个月前
socket02客户端(封装)
  • 发表于 6个月前
  • 阅读 2
  • 收藏 0
  • 点赞 0
  • 评论 0

新睿云服务器60天免费使用,快来体验!>>>   

公共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'

参考

  • 打赏
  • 点赞
  • 收藏
  • 分享
共有 人打赏支持
粉丝 6
博文 2139
码字总数 82983
×
AllenOR灵感
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: