""" 校园内网 TCP 消息通信实训——客户端 ====================================== 运行位置:学生机,或者两人小组中担任“客户端”的B机。 程序会: 1. 输入服务器IPv4地址; 2. 输入一条模拟智能家居数据; 3. 连接服务器5000端口; 4. 发送一条以换行符结束的UTF-8消息; 5. 接收并显示服务器回复。 运行命令: python tcp_client.py 消息示例: TEMP=26.5 SMOKE=1 LAMP=ON """ import socket # 必须与tcp_server.py中的PORT保持一致。 PORT = 5000 # 单条回复最大字节数,与服务器端的课堂限制保持一致。 MAX_MESSAGE_BYTES = 4096 def recv_line(conn: socket.socket) -> str: """持续接收服务器回复,直到遇到换行符。""" buffer = bytearray() while b"\n" not in buffer: chunk = conn.recv(1024) if not chunk: raise ConnectionError("服务器在回复结束前关闭了连接") buffer.extend(chunk) if len(buffer) > MAX_MESSAGE_BYTES: raise ValueError("服务器回复超过4096字节的课堂限制") line, _, _remaining = buffer.partition(b"\n") return line.decode("utf-8") def main() -> None: """连接TCP服务器,发送一条消息并接收回复。""" server_ip = input("TCP服务器IPv4地址:").strip() if not server_ip: print("[ERROR] 服务器IP不能为空。") return message = input("要发送的消息,例如TEMP=26.5:") if not message: print("[ERROR] 消息不能为空。") return try: # AF_INET表示IPv4,SOCK_STREAM表示TCP。 with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as client: # connect、sendall和recv最长等待10秒,避免网络异常时一直卡住。 client.settimeout(10) print(f"[CONNECT] 正在连接 {server_ip}:{PORT} ……") client.connect((server_ip, PORT)) print("[CONNECT] TCP连接建立成功") # TCP不提供消息边界,因此本例人为约定:换行符表示一条消息结束。 payload = (message + "\n").encode("utf-8") client.sendall(payload) print(f"[SEND] {message}") reply = recv_line(client) print(f"[RECV] {reply}") except TimeoutError: print("[ERROR] 连接或通信超时。请检查IP、防火墙、校园网隔离和端口。") except ConnectionRefusedError: print("[ERROR] 连接被拒绝。服务器程序可能没有运行,或5000端口未监听。") except (ConnectionError, UnicodeDecodeError, ValueError, OSError) as exc: print(f"[ERROR] TCP通信失败:{type(exc).__name__}: {exc}") print(" 请查看《端口检查与排错说明.txt》逐层检查。") if __name__ == "__main__": main()