在客户端的 Python 中创建一个聊天应用程序,但有几个我无法弄清楚的问题

Creating a Chat App in Python on the Client Side but there are several issues that I cannot figure out

提问人:TryingMyBest 提问时间:4/26/2023 最后编辑:TryingMyBest 更新时间:4/26/2023 访问量:48

问:

问题 1:

插座过早关闭。 如果用户提供唯一的用户名,则它会正确接受该用户名。 但是,如果用户提供已使用的用户名,则会显示“重试消息”,并要求用户输入新用户名,但由于在用户输入新用户名后套接字过早关闭,因此会显示“来自服务器的意外响应”消息,然后提示用户在弹出错误之前再次输入新用户名([Errno 31] 管道损坏)。

问题 2:

当用户输入“!who”时,将正确显示所有当前登录用户的列表。但是,在显示列表后,用户无法再与服务器交互。没有弹出错误,但服务器变得无响应。

问题 3:

用户键入“!quit”后,没有任何反应。但是,如果用户在所有当前登录用户的列表之后立即键入“!who”,则意味着用户实际上没有关闭客户端。

法典:

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)

# use this to shut down the client???
# def close():
#     server.shutdown(socket.SHUT_RDWR)
#     server.close()
#     print ("closed")

# request unique username from user

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.'
    )
    sys.exit()

  else:
    print('Unexpected response from server.')

  break

user requests list of all currently logged in users

  while True:
  list_request = input()
  if list_request == '!who':
    message1 = 'LIST\n'
    client_sock.sendall(message1.encode())
    response = client_sock.recv(4096).decode()
    if response.startswith('LIST-OK '):
      print('Here is a list of all currently logged in users: {}'.format(response[8:].strip()))
      break

# user asks to shut down the client

while True:
  quit_request = input()
  if quit_request == '!quit':
    sys.exit()

# while True:
#   shutdown_request = input()
#   if shutdown_request == '!quit':
#     close()
#     exit(0)
#     print('Chat clinet has been shutdown.')

# function recieves messages from other users and displays them to the user

def receive():
    while True:
        try:
            # Waiting until data comes in
            # Receive at most 4096 bytes
            data = client_sock.recv(4096).decode()
            if not data:
                    print("Socket is closed.")
            else:
                    print("Socket has data.")
        except OSError as msg:
            print(msg)
            socket.close()
            break

# all possible inputs

# while True:
#   user_input = input(user_name + ': ')

#   if user_input == '!who':
#     message = 'LIST\n'
#     client_sock.sendall(message.encode())
#     response = client_sock.recv(4096).decode()
#     if response.startswith('LIST-OK '):
#       print('Here is a list of all currently logged in users: {}'.format(
#         response[8:].strip()))
#       break

#   if user_input == '!quit':
#     message = shutdown()
#     print('Chat client has been shutdown')

仍在尝试弄清楚如何关闭客户端并防止套接字过早关闭。

python 接字tcp python-multithreading

评论

0赞 bonCodigo 4/26/2023
欢迎来到 StackOverflow!如果你能生成一个导致此错误的“可重现”代码片段,这可能对其他人帮助你有所帮助。

答:

0赞 Tom 4/26/2023 #1

问题 1

在所有 if 语句之后,调用 break。这将退出 while 循环。删除该 while 循环中的第二个中断,如下所示:

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.'
    )
    sys.exit()

  else:
    print('Unexpected response from server.')

问题 2

我将假设:

user requests list of all currently logged in users

  while True:

是格式错误。在这种情况下,while 循环属于与问题 1 相同的问题:

while True:
  list_request = input()
  if list_request == '!who':
    message1 = 'LIST\n'
    client_sock.sendall(message1.encode())
    response = client_sock.recv(4096).decode()
    if response.startswith('LIST-OK '):
      print('Here is a list of all currently logged in users: {}'.format(response[8:].strip()))

问题 3

您提供的代码,鉴于其中一半被注释掉,不会得出这个结论。应该发生的情况是,一旦用户请求表并成功接收它,while 循环就会退出,开始另一个 while 循环,该循环一直运行到用户请求退出为止。

作为一般建议,在代码周围添加 print 语句,以确定代码停止的位置,这样您就可以找到计算机卡住的代码行。