From c05a4c964d6d28e5061c165392e8af6bbe7a1ebf Mon Sep 17 00:00:00 2001 From: wufayuan <2858767122@qq.com> Date: Tue, 15 Mar 2022 16:17:01 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=9D=E6=AD=A5=E5=AE=9E=E7=8E=B0=E6=9C=8D?= =?UTF-8?q?=E5=8A=A1=E5=99=A8=E5=92=8C=E7=BB=88=E7=AB=AF=E8=83=BD=E8=BF=9E?= =?UTF-8?q?=E6=8E=A5=EF=BC=8C=E5=B9=B6=E4=B8=94=E7=BB=88=E7=AB=AF=E5=90=91?= =?UTF-8?q?=E6=9C=8D=E5=8A=A1=E7=AB=AF=E5=8F=91=E8=B5=B7=E8=AF=B7=E6=B1=82?= =?UTF-8?q?=E5=B9=B6=E5=8F=96=E5=BE=97=E5=93=8D=E5=BA=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- conf/settings.ini | 4 + dcs/main.py | 20 ++++- dcs/server.py | 1 - conf/--settings.py => dcs/tests/__init__.py | 0 dcs/tests/client.py | 95 +++++++++++++++++++++ dcs/{ => tests}/requestHandler.py | 8 +- dcs/tests/server.py | 41 +++++++++ 7 files changed, 162 insertions(+), 7 deletions(-) create mode 100644 conf/settings.ini delete mode 100644 dcs/server.py rename conf/--settings.py => dcs/tests/__init__.py (100%) create mode 100644 dcs/tests/client.py rename dcs/{ => tests}/requestHandler.py (76%) create mode 100644 dcs/tests/server.py diff --git a/conf/settings.ini b/conf/settings.ini new file mode 100644 index 0000000..ed61d48 --- /dev/null +++ b/conf/settings.ini @@ -0,0 +1,4 @@ +[server] +port = 7777 +daemon = True + diff --git a/dcs/main.py b/dcs/main.py index 46a9676..dadb562 100644 --- a/dcs/main.py +++ b/dcs/main.py @@ -1,3 +1,19 @@ # -*- coding: UTF-8 -*- -import server -import requestHandler +from dcs.tests.server import Server +from configparser import ConfigParser + +print('reading config args...') +configFile = '../conf/settings.ini' +con = ConfigParser() +con.read(configFile, encoding='utf-8') +items = con.items('server') +items = dict(items) +print(items) + +print('starting the server...') +server = Server(int(items['port'])) +server.daemon = items['daemon'] +server.start() +server.join() + +print('success') diff --git a/dcs/server.py b/dcs/server.py deleted file mode 100644 index 8b13789..0000000 --- a/dcs/server.py +++ /dev/null @@ -1 +0,0 @@ - diff --git a/conf/--settings.py b/dcs/tests/__init__.py similarity index 100% rename from conf/--settings.py rename to dcs/tests/__init__.py diff --git a/dcs/tests/client.py b/dcs/tests/client.py new file mode 100644 index 0000000..ec681c9 --- /dev/null +++ b/dcs/tests/client.py @@ -0,0 +1,95 @@ +# -*- coding: UTF-8 -*- +import struct +from threading import Thread +import socket +from json import JSONEncoder, JSONDecoder +import sys + +# -------------------------------配置-------------------------------------------- +# ------------------------------config-------------------------------------------- + +if len(sys.argv) < 2: + ip = "127.0.0.1" # server的ip +else: + ip = sys.argv[1] +port = 7777 # server的port + + +def read_bytes(s: 'socket.socket', size: 'int') -> 'bytes': + """ + 从socket读取size个字节 + :param s:套接字 + :param size:要读取的大小 + :return:读取的字节数,在遇到套接字关闭的情况下,返回的数据的长度可能小于 size + """ + data = ''.encode('utf-8') + while len(data) < size: + rsp_data = s.recv(size - len(data)) + data += rsp_data + if len(rsp_data) == 0: + break + return data + + +def generate_request(request) -> 'bytes': + """ + 根据传入的dict生成请求 + 请求包含 8字节头长度+头数据 + :param request: dict + :return: bytes 请求数据 + """ + request_bytes = JSONEncoder().encode(request).encode("utf-8") + return struct.pack("!Q", len(request_bytes)) + request_bytes + + +class Client(Thread): + def __init__(self, ip: str, port: int) -> None: + """ + :param ip: 服务器IP + :param port: 服务器端口 + """ + super().__init__() + self.ip = ip + self.port = port + + def test(self) -> 'int': + with socket.socket(socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_TCP) as socket_to_server: + socket_to_server.connect((self.ip, self.port)) + request = dict() + request['action'] = 'test' + + full_request = generate_request(request) + + socket_to_server.sendall(full_request) + + responseJson = JSONDecoder().decode( + read_bytes(socket_to_server, struct.unpack('!Q', socket_to_server.recv(8))[0]).decode( + "utf-8")) + + return responseJson['test'] + + def end(self): + """ + 结束通信 + :return: + """ + with socket.socket(socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_TCP) as socket_to_server: + socket_to_server.connect((self.ip, self.port)) + request = dict() + request['action'] = 'end' + + full_request = generate_request(request) + + socket_to_server.sendall(full_request) + + print("end communication!") + + def run(self) -> None: + self.test() + self.end() + + +download_task = Client(ip, port) +download_task.daemon = True +download_task.start() +download_task.join() diff --git a/dcs/requestHandler.py b/dcs/tests/requestHandler.py similarity index 76% rename from dcs/requestHandler.py rename to dcs/tests/requestHandler.py index a26c914..4be1a34 100644 --- a/dcs/requestHandler.py +++ b/dcs/tests/requestHandler.py @@ -15,10 +15,10 @@ class RequestHandler(threading.Thread): def run(self) -> None: try: - if self.request_map['action'] == 'getFileSize': - print(f"[REQUEST] getFileSize") + if self.request_map['action'] == 'test': + print(f"[REQUEST] test") response = { - 'fileSize': self.file_server.get_file_size() + 'test': 'hello TEST' } response_binary = json.JSONEncoder().encode(response).encode("utf-8") response_binary_len = len(response_binary) @@ -26,6 +26,6 @@ class RequestHandler(threading.Thread): response_binary = response_binary_len_binary + response_binary self.client_socket.sendall(response_binary) - print(f"[RESPONSE] file size: {response['fileSize']}, header size: {response_binary_len}") + print(f"[RESPONSE] test: {response['test']}, header size: {response_binary_len}") finally: self.client_socket.close() diff --git a/dcs/tests/server.py b/dcs/tests/server.py new file mode 100644 index 0000000..875fa04 --- /dev/null +++ b/dcs/tests/server.py @@ -0,0 +1,41 @@ +import threading +import socket +import json +import struct +from dcs.tests.requestHandler import RequestHandler + + +def read_bytes(s: 'socket.socket', size: 'int') -> 'bytes': + data = ''.encode('utf-8') + while len(data) < size: + rsp_data = s.recv(size - len(data)) + data += rsp_data + if len(rsp_data) == 0: + break + return data + + +class Server(threading.Thread): + def __init__(self, port: 'int'): + super().__init__() + self.port: 'int' = port + self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_TCP) + self.server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + self.server_socket.bind(('', port)) + self.buffer_size = 8 * 1024 * 1024 + + def run(self) -> None: + self.server_socket.listen() + while True: + client_socket, _ = self.server_socket.accept() + request_header_size = struct.unpack("!Q", read_bytes(client_socket, 8))[0] + request_map = json.JSONDecoder().decode(read_bytes(client_socket, request_header_size).decode("utf-8")) + print(request_map) + # end请求要在主线程处理,不然退出就不会及时响应 + if request_map['action'] == 'end': + print(f"[REQUEST] end") + print("communication over!") + break + r = RequestHandler(self, client_socket, request_map) + r.start() + self.server_socket.close()