ich bin neu hier im Forum und hoffe hier etwas Hilfe zu bekommen. Vorher gesagt, ich beschäftige mich schon recht lange mit Python aber ich bin alles andere als ein Profi. Man fängt ja immer irgendwo an.
Ich brauche ein bisschen Hilfe bezüglich sockets, angepasst auf mein Programm, was ich gerade schreibe. Kurze Erklärung zum Programm: Ich möchte von überall aus meine Computer Zuhause steuern. Ich habe zwei Computer und dort befindet sich dann ein Python Script mit der Klasse Clients. Dann habe ich ein Server im Internet mit nem Script, welche die Klasse Server enthält. Der Server steuert alle Verbindungen. Dann habe ich noch einen anderen Client, der einfach als Benutzeroberfläche für die Steuerung dient. Um es anschaulicher zu machen:
Ich schicke über meinen Steuerclient die Nachricht "hello computer1" an den Server. Der Server erkennt, dass es der Steuerclient ist und schickt die Nachricht an den Client auf mein Computer1 zuhause weiter. Computer1 schickt an den Server "Hello World" an den Server. Server erkennt, dass es sich um den Client von Zuhause handelt und schickt die Nachricht an meinen Steuerclient weiter.
Ich denke das Prinzip ist klar.
Leider habe ich scheinbar das Prinzip von socket im Kombination mit Multithreading nicht ganz verstanden. Ich bekomme immer ein BrokenPipeError. Kann mir jemand erklären, was ich falsch mache?
Ich habe schon etwas an Code. Ich denke es ist klar, was mein Ziel ist. Danke im Vorraus!
Server:
Code: Alles auswählen
from http import client
from threading import Thread
from time import sleep
import ctypes, socket, sys
from typing import Tuple
class UserClient():
username = ""
password = ""
connection = ""
def __init__(self, username, password, permissions ,conn: socket) -> None:
self.username = username
self.password = password
self.conn = conn
self.perms = permissions
def take_commands(self):
while True:
self.conn.send("cmd".encode())
cmd = self.conn.recv(1024).decode()
if(cmd == "help"):
self.conn.send("help".encode())
class Server():
def __init__(self, ip: str, port: int, hostname: str) -> None:
self.hostname = hostname
self.bots = []
self.clients = []
self.dead_bots = []
self.connection = (ip, port)
self.running = True
if self.bind(self.connection):
print("Started")
def bind(self, connection: Tuple[str, int]) -> bool:
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.bind(connection)
self.sock.listen()
print("Listening to Clients...")
Thread(target=self.collect).start()
return True
def collect(self):
while self.running:
try:
conn, addr = self.sock.accept()
if addr not in self.bots:
recv = self.recv(conn)
if recv.startswith("c"):
creds = recv.split("#")
user, passw, permissions = self.check_login(creds[1], creds[2])
if permissions != None:
self.send(conn, "accepted " + self.hostname)
self.broadcast_clients(f"New Client: {conn.getpeername()}")
user = UserClient(user, passw, permissions, conn)
self.clients.append(user)
Thread(target=user.take_commands).start()
else:
self.broadcast_clients(f"Invalid Login: {conn.getpeername()}")
self.send(conn, "invalid creds")
elif recv.startswith("b"):
pass
except socket.timeout:
continue
except socket.error:
continue
pass
def broadcast_clients(self, message: str):
send = f"[{self.hostname}] » " + message
print(send)
for client in self.clients:
self.send_and_recv(client, send)
def send_and_recv(self, client, data: str) -> str:
client.send(data.encode())
return client.recv(1024).decode()
def send(self, client, data: str):
client.send(data.encode())
def recv(self, client) -> str:
return client.recv(1024).decode()
def check_login(self, username: str, password: str):
with open("./creds.txt") as f:
logins = [x.strip() for x in f.readlines()]
for login in logins:
cred_types = login.split(":")
user = cred_types[0]
passw = cred_types[1]
permissions = cred_types[2].split(".")
if user == username and passw == password:
return user, passw, permissions
else:
return None
def main():
Server("localhost", 1337, "fsocietyNET")
if __name__ == "__main__":
main()
Code: Alles auswählen
import socket
from threading import Thread
from typing import Tuple
class Client():
def __init__(self, conn: Tuple[str, int], username: str, password: str) -> None:
self.hostname = ""
self.username = username
self.password = password
self.prefix = ""
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.settimeout(5)
if self.bind(conn):
if self.login():
Thread(target=self.command_terminal).start()
else:
print("invalid creds")
else:
print("err")
def bind(self, conn: Tuple[str, int]) -> bool:
try:
self.sock.connect(conn)
return True
except socket.timeout or socket.error:
return False
def login(self) -> bool:
data = f"c#{self.username}#{self.password}"
recv = self.send_and_recv(data)
if recv.startswith("accepted"):
self.hostname = recv.split(" ")[1]
self.prefix = f"{self.username}@{self.hostname}$ "
return True
else:
return False
def send_and_recv(self, data) -> str:
self.sock.send(data.encode())
return self.sock.recv(1024).decode()
def send(self, data):
self.sock.send(data.encode())
def recv(self) -> str:
return self.sock.recv(1024).decode()
def command_terminal(self):
while True:
command = input(self.prefix)
recv = self.send_and_recv(command)
if(recv) == "what":
print("[!] Unknown command.")
else:
print(recv)
def main():
print("Welcome to my Homenetwork!")
user = input("Username: ")
password = input("Password: ")
conn = ("127.0.0.1", 1337)
client = Client(conn, user, password)
if __name__ == "__main__":
main()