You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python Socket实现服务端向客户端返回ping结果的问题咨询

现有代码问题排查
  • 服务端返回逻辑位置错误:conn.sendall(dataFromClient)放在了客户端断开连接的break之后,只有客户端下线才会执行,且此时dataFromClient为空,无法正常返回数据
  • 业务逻辑颠倒:ping操作的执行逻辑写在了客户端,不符合「服务端发起ping」的需求
  • 客户端收包逻辑被注释,无法接收服务端的任何返回内容
  • 无统一的指令/返回协议,两端无法识别对方发送的内容含义
  • 未处理TCP粘包问题,长输出内容会出现乱码、拼接错误
实现方案

我们先约定统一的交互协议:

  1. 连接建立后,客户端发送check指令,服务端返回online即代表服务端在线
  2. 客户端发送ping指令格式为ping|目标IP| ping次数,例如ping|223.5.5.5|4
  3. 服务端返回内容末尾统一加[EOF]作为结束标记,解决TCP粘包问题

修正后服务端代码

#!/usr/bin/python3
import socket
import sys
import subprocess
import platform

HOST = '0.0.0.0'  # 本地测试可保留127.0.0.1,改0.0.0.0允许外网客户端连接
PORT = 8085

# 跨平台ping命令参数适配
ping_param = '-n' if platform.system().lower() == 'windows' else '-c'

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print('Socket created')

# 绑定端口
try:
    s.bind((HOST, PORT))
except socket.error as msg:
    print(f'Bind failed. Error Code : {msg[0]} Message {msg[1]}')
    sys.exit()

print('Socket bind complete')

# 启动端口监听
s.listen(10)
print('Socket now listening')

while 1:
    conn, addr = s.accept()
    print(f'Connected from {addr}')

    while True:
        dataFromClient = conn.recv(1024).decode('utf-8').strip()
        if not dataFromClient:
            print("[Client] Disconnected")
            break
        print(f"Received command: {dataFromClient}")
        
        # 处理在线检测指令
        if dataFromClient == 'check':
            conn.sendall(b'online[EOF]')
        # 处理ping指令
        elif dataFromClient.startswith('ping|'):
            _, target, count = dataFromClient.split('|')
            cmd = ['ping', ping_param, count, target]
            try:
                result = subprocess.run(cmd, capture_output=True, text=True, timeout=10)
                output = result.stdout + result.stderr
            except Exception as e:
                output = f"Ping execution error: {str(e)}"
            conn.sendall(f"{output}[EOF]".encode('utf-8'))
        # 未知指令处理
        else:
            conn.sendall(b'Unknown command[EOF]')
    conn.close()
s.close()

修正后客户端代码

#!/usr/bin/python3
import socket
import os

SERVER = "127.0.0.1"
PORT = 8085

def recv_full_data(sock):
    """接收完整数据直到遇到结束标记[EOF],解决TCP粘包问题"""
    data = b''
    while True:
        part = sock.recv(1024)
        if not part:
            break
        data += part
        if b'[EOF]' in data:
            break
    return data.replace(b'[EOF]', b'').decode('utf-8')

clientSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
    clientSocket.connect((SERVER, PORT))
except Exception as e:
    print(f"Connect to server failed: {str(e)}")
    exit()

os.system("clear||cls")

while True:
    data = input("Input: ").strip()
    if not data:
        continue
    # 退出指令
    if data == 'exit':
        break
    # 发送指令给服务端
    clientSocket.send(data.encode('utf-8'))
    # 接收服务端返回
    resp = recv_full_data(clientSocket)
    
    if data == "check":
        print(f"Server status: {resp}")
    elif data == "ping":
        target = input("Enter ping target IP: ").strip()
        count = input("Enter ping times: ").strip()
        # 拼装ping指令发送
        clientSocket.send(f"ping|{target}|{count}".encode('utf-8'))
        ping_result = recv_full_data(clientSocket)
        print("Ping result from server:")
        print(ping_result)
    elif data == "help":
        print("Supported commands:")
        print("- check: Check if server is online")
        print("- ping: Execute ping on server and get result")
        print("- help: Show help info")
        print("- exit: Exit client")
    else:
        print(f"Server response: {resp}")
clientSocket.close()
使用说明
  1. 先启动服务端脚本,再启动客户端脚本
  2. 客户端输入check即可检测服务端是否在线
  3. 客户端输入ping按照提示输入目标IP和ping次数,即可获取服务端执行的ping原始输出
  4. 客户端输入help可查看所有支持的指令
  5. 客户端输入exit即可退出

内容的提问来源于stack exchange,提问作者whipflashx

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 07:09:03