Python клиент зависает при отправке пустого сообщения на сервер - PullRequest
0 голосов
/ 24 февраля 2020

У меня есть обратная оболочка python, над которой я работаю, которая использует соединение клиент-сервер по протоколу TCP. Я тестирую их обоих прямо сейчас на моем компьютере localhost windows и использую библиотеку подпроцесса для обработки команд. Предполагается, что клиент отправит команду на сервер, а сервер ответит ответом.

Сервер:

import socket
import subprocess
import os

# Server

# creates TCP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# port and server ip(localhost)
LOCAL_HOST = '127.0.0.1'
PORT = 5565

BUFFER_SIZE = 5000  # size of message

no_char_message = "-1: Please enter a command"


# test connection
print("Server starting up on %s with port number %s" % (LOCAL_HOST, PORT))
# bind socket to ip and port
sock.bind((LOCAL_HOST, PORT))
# listen to socket
sock.listen(1)

# socket will accept connection and client address

print("Waiting for connection")  # waiting for connection
connection, address = sock.accept()  # accept connection with client address
print("Connected to", address)  # connected by address
while True:
    command = connection.recv(BUFFER_SIZE)  # receive message from client
    if not command:
        break
    if len(command) == 0:
        connection.send(str.encode(no_char_message))
    if len(command) > 0:
        terminal = subprocess.Popen(command[:].decode("utf-8"), shell=True, stdout=subprocess.PIPE,
                                    stderr=subprocess.PIPE, stdin=subprocess.PIPE)
        output = terminal.stdout.read() + terminal.stderr.read()
        output_as_string = str(output, "utf-8")
        connection.send(str.encode(output_as_string))
        print(output_as_string)
print("Closing Server")
sock.close()
connection.close()

Клиент

import socket

# Client
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  # creates TCP Socket

# local host and port
LOCAL_HOST = '127.0.0.1'

PORT = 5565
BUFFER_SIZE = 5000  # size of message

# connect socket to ip and port
sock.connect((LOCAL_HOST, PORT))
print("Connected to server\n")
while True:

    message = input("Please enter a command:\n")  # ask user to input message
    if message == 'quit':
        break
    print("Sending %s" % message)
    sock.send(str.encode(message))  # send message
    command = str(sock.recv(BUFFER_SIZE), "utf-8")  # receive message
    print("received %s" % command)
print("closing connection with server")
sock.close()

Проблема заключается в том, что когда я отправляю пустое сообщение на сервер, он зависает и просто говорит, что отправка в терминале и Сервер никогда ничего не получает. Я не уверен, что является причиной этого, но я предполагаю, что трубы заблокированы, или что я не обращаюсь с этим правильно.

Я хочу, чтобы сервер возвращал сообщение об ошибке клиенту, а не обрабатывал сообщение об ошибке в самом клиенте.

Я попытался проверить условие, если длина команды равна 0, и обработать его с сообщением об ошибке, но оно не сработало и все еще зависает.

Программа также, кажется, зависает при попытке например команда date.

В общем, как мне обработать условие, если команда не распознана, пуста или не выполнена успешно?

1 Ответ

1 голос
/ 24 февраля 2020

TCP не имеет понятия пустого сообщения. TCP вообще не имеет понятия сообщения, он знает только байты. Таким образом, если вы вызываете send с пустой строкой, он просто ничего не отправляет (не пустой пакет, а пакет вообще) на сервер, что означает, что серверу нечего принимать - он все равно будет блокироваться во время ожидания данных. Другими словами: нет пустой команды, просто нет никакого комментария.

if len(command) == 0:

Это не будет проверять пустое сообщение (которое снова не существует), но сработает, если клиент закроет подключение. Любая проверка на пустую команду уже должна была быть выполнена на клиенте.

...