So erstellen Sie eine neue Socket-Verbindung mit Multithreading in PythonPython

Python-Programme
Anonymous
 So erstellen Sie eine neue Socket-Verbindung mit Multithreading in Python

Post by Anonymous »

Das Projekt, an dem ich arbeite, ist eine Simulation/ein Modell eines VPN-Dienstes. Ich habe herausgefunden, wie man mehrere Clients mithilfe von Schleifen und Multithreading mit einem einzelnen Server verbindet, aber jetzt fällt es mir schwer herauszufinden, wie ich Informationen selektiv zwischen diesen Threads weiterleiten und jede Verbindung aufrechterhalten kann. Der Prozess, wie ich ihn mir vorgestellt habe, ist dieser.
  • Starten Sie den Server und warten Sie auf eingehende Verbindungen
  • Starten Sie andere Clients und lassen Sie sie eine Verbindung zum Server herstellen
  • Wenn der Benutzer-Client eine Verbindung herstellt, sollte der Server dies erkennen und den Benutzer-Thread starten
  • Benutzer-Client sollte Daten an den Server senden, die ihm mitteilen, zu welchem Client eine Verbindung hergestellt werden soll
  • Der Server sollte dann mit dem Tunneln von Informationen zwischen dem Benutzer-Client und dem ausgewählten Client beginnen
Das Problem besteht darin, dass ich aufgrund der Art und Weise, wie die Schleife zum Verbinden aller Clients funktioniert, keine Möglichkeit habe, auszuwählen, welche Verbindungen offen bleiben oder durch welche Verbindungen getunnelt werden sollen. Alle Verbindungen werden gleichzeitig unter demselben Namen erstellt und rufen dieselbe Funktion auf, um ihre Prozesse auszuführen. Hier ist der Code, mit dem ich als Basis arbeite.

Code: Select all

def handle_client(conn, addr):
print(f"Connection established with {addr}.")

while True:
try:
data = conn.recv(1024)  # Receive data from the client
if not data:
break  # Terminate the connection if no data is received
print(f"Received from {addr}: {data.decode()}")
conn.sendall(f"Server response: {data.decode()}".encode())  # Send the received data back to the client
except ConnectionResetError:
print(f"Client {addr} has disconnected.")
break
conn.close()
print(f"Connection with {addr} closed.")# Start the server

def start_server():
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as server_socket:
server_socket.bind((HOST, PORT))
server_socket.listen()
print(f"Server listening on {HOST}:{PORT}...")

while True:
conn, addr = server_socket.accept()  # Accept a client connection
thread = threading.Thread(target=handle_client, args=(conn, addr))
thread.start()  # Start a new thread for each client
print(f"Active connections: {threading.activeCount() - 1}")

if __name__ == "__main__":
start_server()
Und hier ist der geänderte Code, den ich geschrieben habe. Mein Gedanke war, die while-True-Schleife abzuschaffen und nur eine ausgewählte, begrenzte Anzahl anderer Client-Verbindungen aufrechtzuerhalten, die für einen einfacheren Zugriff namentlich aufgerufen werden könnten. Ich habe außerdem eine dedizierte Funktion zur Bedienung der Benutzer-Client-Verbindung hinzugefügt, die aufgerufen wird, wenn die entsprechende IP-Adresse erkannt wird. Schließlich habe ich eine Warteschlange hinzugefügt, um Informationen zwischen dem Benutzer und dem ausgewählten Client zu tunneln.

Code: Select all

##Code to handle user cLient
def handle_user(conn, addr,in_q):
print(f"Connection established with {addr}.")
while True:
try:
data = conn.recv(1024).decode()  # Receive data from the client
if not data:
break  # Terminate the connection if no data is received
in_q.put(data)
time.sleep(3)
toClient = in_q.get()
conn.sendall({data.encode()})
except ConnectionResetError:
print(f"Client {addr} has disconnected.")
break
conn.close()
print(f"Connection with {addr} closed.")# Start the server

#code to handle other clients
def handle_client(conn,addr):
print(f"Connection established with {addr}.")
while True:
try:
conn.sendall()
data = conn.recv(1024)  # Receive data from the client
if not data:
break  # Terminate the connection if no data is received
print(f"Received from {addr}: {data.decode()}")
conn.sendall(f"Server response: {data.decode()}".encode())  # Send the received data back to the client
except ConnectionResetError:
print(f"Client {addr} has disconnected.")
break
conn.close()

def start_server():
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as server_socket:
server_socket.bind((HOST, PORT))
server_socket.listen()
print(f"Server listening on {HOST}:{PORT}...")

q = Queue() #create a new queue
while True:
conn, addr = server_socket.accept()  # Accept a client connection
if addr == '10.9.0.2':
User_thread = threading.Thread(target=handle_user, args=(conn, addr,q))
User_thread.start()  # Start thread to handle User
conn.sendall(f"Which server would you like to connect to?\n0)to termiante connection\n1)UK\n2)Nowray\n3)Egypt")
data = conn.recv(1024).decode()  # Receive data from the client
if data == 1:
t1.start()
elif data == 2:
t2.start()
elif data == 3:
t3.start()
elif addr == '10.9.0.3':
t1 = threading.Thread(target=handle_client, args=(conn, addr,q))
# Start a new thread for each client
elif addr == '10.9.0.4':
t2 = threading.Thread(target=handle_client, args=(conn, addr,q))
t2.start()  # Start a new thread for each client
elif addr == '10.9.0.5':
t3 = threading.Thread(target=handle_client, args=(conn, addr,q))
t3.start()  # Start a new thread for each client
print(f"Active connections: {threading.activeCount() - 1}")

if __name__ == "__main__":
start_server()
Wie Sie sehen können, ist es ein Chaos. Mein erster Gedanke war, den Handle-User-Thread mit dem Benutzer sprechen zu lassen und ihn auszuwählen, mit welchem ​​anderen Client er eine Verbindung herstellen möchte. Aber das scheiterte, als mir klar wurde, dass es keine saubere Möglichkeit gab, diese Informationen an Main zurückzugeben, ohne den Thread zu beenden und die Verbindung mit dem Benutzer zu schließen. Also habe ich versucht, diesen Prozess in die Main-Funktion selbst zu verschieben und die anderen Threads basierend auf der Verbindung des Benutzers zu starten, aber jetzt bin ich mir nicht sicher, ob die alte Verbindung, die an die Client-Threads übergeben wird, von der Schleife überschrieben wird, wenn die Threads nur in der Iteration gestartet werden, in der der Benutzer eine Verbindung herstellt.
TLDR: Ich brauche eine Möglichkeit, basierend auf den Eingaben des Benutzer-Threads auszuwählen, mit welchen Threads ich zu einem bestimmten Zeitpunkt arbeite

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post