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

Python客户端聊天应用开发求助:Socket异常与功能故障

Python聊天客户端Socket问题修复方案

问题1:Socket过早关闭

根源:用户名输入循环末尾的break语句导致循环仅执行一次。输入已占用用户名时,提示重试后循环直接退出,客户端处于未完成登录的异常状态,后续发送数据触发Socket错误。

修复:移除循环末尾的break,仅在成功登录或服务器繁忙时退出循环:

while True:
  user_name = input('Enter a unique user name: ')
  message = 'HELLO-FROM {}\n'.format(user_name)
  client_sock.send(message.encode())
  response = client_sock.recv(4096).decode()

  if response.startswith('HELLO '):
    print('You are logged in as {}'.format(response[6:].strip()))
    break

  elif response == 'IN-USE\n':
    print('That username is already in use. Please input an alternative.')

  elif response == 'BUSY\n':
    print('The maximum number of clients has been reached. Please try again later.')
    client_sock.close()
    sys.exit()

  else:
    print('Unexpected response from server.')
    client_sock.close()
    sys.exit()

问题2:!who操作后服务器无响应

根源:

  1. !who循环执行一次后就break,退出输入处理逻辑,无法接收后续用户指令;
  2. receive函数未启动线程,无法监听服务器主动推送的消息,导致看似服务器无响应。

修复:

  • 合并所有输入处理逻辑为一个循环;
  • 启动receive线程持续监听服务器消息:
def receive():
    while True:
        try:
            data = client_sock.recv(4096).decode()
            if not data:
                print("\n服务器已断开连接")
                client_sock.close()
                sys.exit()
            if data.startswith('LIST-OK '):
                print(f"\n在线用户列表: {data[8:].strip()}")
            else:
                print(f"\n服务器消息: {data}")
        except OSError as msg:
            print(f"\n连接错误: {msg}")
            break

# 启动接收线程
receive_thread = threading.Thread(target=receive)
receive_thread.daemon = True  # 主线程退出时自动终止子线程
receive_thread.start()

# 统一输入处理循环
while True:
  user_input = input(f"{user_name}: ")
  if user_input == '!who':
    client_sock.sendall('LIST\n'.encode())
  elif user_input == '!quit':
    client_sock.sendall('QUIT\n'.encode())
    client_sock.close()
    sys.exit()
  # 可添加普通聊天消息处理逻辑

问题3:!quit功能失效

根源:

  1. !quit逻辑为独立循环,未与主输入流程整合,无法被触发;
  2. 直接调用sys.exit()未关闭Socket,也未通知服务器客户端退出,导致服务器仍认为客户端在线。

修复:将!quit逻辑整合到统一输入循环中,退出前先向服务器发送退出指令并关闭Socket,如上述修复代码所示。

完整修复代码示例

import socket
import threading
import sys

client_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host_port = ("123.37.104.311", 1200)
client_sock.connect(host_port)

def receive():
    while True:
        try:
            data = client_sock.recv(4096).decode()
            if not data:
                print("\n服务器已断开连接")
                client_sock.close()
                sys.exit()
            if data.startswith('LIST-OK '):
                print(f"\n在线用户列表: {data[8:].strip()}")
            else:
                print(f"\n{data}")
        except OSError as msg:
            print(f"\n连接错误: {msg}")
            break

# 用户名登录流程
user_name = ""
while True:
  user_name = input('Enter a unique user name: ')
  message = 'HELLO-FROM {}\n'.format(user_name)
  client_sock.send(message.encode())
  response = client_sock.recv(4096).decode()

  if response.startswith('HELLO '):
    print('You are logged in as {}'.format(response[6:].strip()))
    break

  elif response == 'IN-USE\n':
    print('That username is already in use. Please input an alternative.')

  elif response == 'BUSY\n':
    print('The maximum number of clients has been reached. Please try again later.')
    client_sock.close()
    sys.exit()

  else:
    print('Unexpected response from server.')
    client_sock.close()
    sys.exit()

# 启动接收线程
receive_thread = threading.Thread(target=receive)
receive_thread.daemon = True
receive_thread.start()

# 主输入循环
while True:
  try:
    user_input = input(f"{user_name}: ")
    if user_input == '!who':
      client_sock.sendall('LIST\n'.encode())
    elif user_input == '!quit':
      client_sock.sendall('QUIT\n'.encode())
      print("正在退出...")
      client_sock.close()
      sys.exit()
    else:
      print("请输入!who查看在线用户,!quit退出")
  except KeyboardInterrupt:
    client_sock.sendall('QUIT\n'.encode())
    client_sock.close()
    sys.exit()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 10:55:00