简单的通信示例
使用 TCP 连接
模拟 TCP 客户端发送,服务端回复(循环接收)
file:server.py1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| import socket
server = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM)
ip = '127.0.0.1' port = 8001 server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server.bind((ip, port))
server.listen(5) while True: conn, addr = server.accept() print(f"客户端地址: {addr}") while True: try: from_client_to_server_recv_data = conn.recv(1024) if not from_client_to_server_recv_data: break result = from_client_to_server_recv_data.decode() if result == 'q': break print(f"data_from_client :>>>> {result}") from_server_to_client_send_data = input("请输入给客户端的数据 :>>>> ").strip() conn.send(from_server_to_client_send_data.encode("utf-8")) except Exception as e: break conn.close()
server.close()
|
file:client.py1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| import socket client = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM)
ip = '127.0.0.1' port = 8001
client.connect((ip, port))
while True: data_to_server = input("请输入给服务端的数据 :>>>> ").strip()
if not data_to_server: continue
client.send(data_to_server.encode("utf-8")) if data_to_server == "q": break data_from_server = client.recv(1024) result = data_from_server.decode() if result == "q": break print(f"data_from_server :>>>> {result}") client.close()
|
使用 UDP 连接
模拟 UDP 客户端发送小写字母,服务端回复大写字母(循环接收)
file:server.py1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| from socket import socket, AF_INET, SOCK_DGRAM
server = socket(family=AF_INET, type=SOCK_DGRAM)
addr = "127.0.0.1" port = 8001 server.bind((addr, port))
print(f"server:>>>{server}") while True: from_client_recv_data, client_addr = server.recvfrom(1024) print(f"server:>>>{from_client_recv_data.decode()}") print(f"client_addr:>>>{client_addr}") to_client_send_data = from_client_recv_data.decode().upper() server.sendto(to_client_send_data.encode("utf-8"), client_addr)
|
file:client.py1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| from socket import socket, AF_INET, SOCK_DGRAM
server = socket(family=AF_INET, type=SOCK_DGRAM) addr = "127.0.0.1" prot = 8001
while True: data_to_server = input("请输入给服务端的数据 :>>>> ").strip() if not data_to_server: continue client.sendto(data_to_server.encode("utf-8"), (addr, prot)) data_from_server, server_addr = client.recvfrom(1024) print(f"data_from_server :>>>> {data_from_server.decode()}")
|
TCP 粘包问题
让服务端知道客户端发来的数据总大小,动态的指定可接收数据大小
eg:模拟客户端下载服务端图片文件(服务端图片 hello.png,客户端输入 hello 即可下载)
file:server.py1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
| import hashlib import json import os.path import socket import struct import subprocess def read_data(file_name): file_path = os.path.join(os.path.dirname(__file__), file_name + '.png') with open(file_path, 'rb') as fp: data = fp.read() return data server = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM, proto=0)
addr = "127.0.0.1" port = 8001 server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) server.bind((addr, port)) server.listen(5) while True: client_socket, client_addr = server.accept() print(f"客户端地址{client_addr}已连接") while True: try: data_from_client = client_socket.recv(1024) if not data_from_client: break file_name = data_from_client.decode('utf-8') if file_name == 'q': break file_data = read_data(file_name=file_name) data_to_client_bytes_len = len(file_data) print(data_to_client_bytes_len) md5 = hashlib.md5() md5.update(file_data) file_data_dict = { "file_name": file_name, "file_hex": md5.hexdigest(), "file_type": "png", "data_all": data_to_client_bytes_len } file_data_dict_str = json.dumps(file_data_dict) file_data_dict_bytes = file_data_dict_str.encode('utf-8') pack_data = struct.pack('i', len(file_data_dict_bytes)) client_socket.send(pack_data) client_socket.send(file_data_dict_bytes) client_socket.send(file_data) except Exception as e: break client_socket.close() server.close()
|
file:client.py1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| import hashlib import json import os.path import socket import struct client = socket.socket()
addr = "127.0.0.1" port = 8001 client.connect((addr, port)) while True: data_to_server = input("请输入请求服务器的数据:>>> ").strip() if not data_to_server: continue client.send(data_to_server.encode("utf-8")) if data_to_server == "q": break pack_data = client.recv(4) print(pack_data) json_data_length_all = struct.unpack("i", pack_data)[0] file_data_dict = json.loads(client.recv(json_data_length_all)) data_length_all = file_data_dict.get("data_all") print(f"data_length_all : >>> {data_length_all}") count_data = 0 data = b"" buffer_size = 1024 while count_data < data_length_all: data += client.recv(buffer_size) count_data += buffer_size md5 = hashlib.md5() md5.update(data) file_hex = file_data_dict.get("file_hex") print(f"old_hex : >>> {file_hex}") print(f"new_hex : >>> {md5.hexdigest()}") if file_hex != md5.hexdigest(): print("文件已损坏!") break file_name = "nb_" + file_data_dict.get("file_name") file_type = file_data_dict.get("file_type") file_path = os.path.join(os.path.dirname(__file__), file_name + "." + file_type) with open(file_path, "wb") as fp: fp.write(data)
|