Python Socket закрывается после одного соединения / команды - PullRequest
0 голосов
/ 27 июня 2018

Клиент и сервер могут успешно соединиться, однако можно выполнить только одну команду. Поработав некоторое время и попросив помощи извне, любые отзывы или предложенные улучшения будут очень благодарны заранее.

Просматривал другие посты, которые предполагают, что я, возможно, преждевременно закрыл соединение, но я не верю, что это правда, потому что программа не выдает никаких ошибок разъединения, хотя я могу ошибаться.

client.py

import socket
import sys
import os

# Create a TCP/IP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

##server = input("Enter server IP: ")
##print(server)
##
##port = int(input("Enter port: "))
##print(port)

def send_msg(msg):
    sock.sendall(msg.encode())

def get_msg():
    msg = sock.recv(2048).decode()
    return msg

server = "127.0.0.1"
port = 100

sock.connect((server, port))
print("Connecting to " + server + " on port " + str(port) + "\n")

while True:
    #Send data
    msg = input(os.getcwd() + "> ")
    print("Sending '" + msg + "'")
    send_msg(msg)

    #Response
    #amnt_exp = len(msg)
    #data = sock.recv(2048)
    data = get_msg()

    if data == "exit":
        print("\nClosing connection")
        sock.close()
    else:
        print("Received: \n" + data)

server.py

import socket
import sys
import os
import subprocess

#Create a TCP/IP Socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

##server = input("Enter server IP: ")
##print(server)
##
##port = int(input("Enter port: "))
##print(port)

def send_msg(msg):
    conn.sendall(msg.encode())

def get_msg():
    msg = conn.recv(2048).decode()
    return msg

server = "127.0.0.1"
port = 100

#Config
sock.bind((server, port))
print("Bound to " + server + " on port " + str(port) + "\n")


sock.listen(1)
print("Waiting for a connection...")
while True:
    conn, caddr = sock.accept()
    print("Connected!\n")
    print("Waiting for a command...")

    #data = conn.recv(2048).decode()
    data = get_msg()

    #Exit
    if data == "exit":
        print("\nConnection closed")
        conn.close()

    print("Received '" + data + "'")
    #Command Exec
    call = subprocess.Popen(data, stdout = subprocess.PIPE, shell=True)

    #Output
    output, err = call.communicate()
    call_status = call.wait()

    #print("Output: ", output)
    #print("Exit status: ", call_status)

    #Reply
    msg = "Command successful\n" + "Output: " + str(output) + "\n" + "Exit status:" + str(call_status) 
    print("Sending reply...")
    print("\nWaiting for a command...")
    send_msg(msg)

1 Ответ

0 голосов
/ 27 июня 2018

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

Ваш вывод вводит в заблуждение, потому что он выводит Waiting for a command.... Но это происходит только потому, что у вас есть дополнительные print("\nWaiting for a command...") до send_msg, а у вас нет вывода до sock.accept. Вы можете видеть, что на самом деле происходит, если вы делаете свои отпечатки точными. Например:

sock.listen(1)
while True:
    print('Waiting for a connection...') # inside the loop, not before it
    conn, caddr = sock.accept()
    # ... etc. ...
    print("Sending reply...")
    # Don't print Waiting for a command here, because you aren't
    send_msg(msg)
    # And print something after the send succeeds
    print("Sent")
    print()

Итак, теперь вы знаете, что не так, как вы можете это исправить?

Simple. Нам просто нужен вложенный цикл. Как только вы accept подключитесь к клиенту, продолжайте использовать это подключение до тех пор, пока оно не выйдет:

sock.listen(1)
while True:
    print('Waiting for a connection...') # inside the loop, not before it
    conn, caddr = sock.accept()
    print("Connected!\n")

    while True:
        print("Waiting for a command...")
        data = get_msg()

        #Exit
        if data == "exit":
            print("\nConnection closed")
            conn.close()
            break # go back to the outer accept loop to get the next connection

        print("Received '" + data + "'")
        # ... etc. ...
        print()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...