socket02客户端(封装)

2017-05-02  本文已影响46人  极光火狐狸

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

参考

上一篇下一篇

猜你喜欢

热点阅读