forked from 20241144010013/20241144010013
Add simple networking module and test
This commit is contained in:
parent
276b090cfd
commit
055e4fa224
|
@ -0,0 +1,130 @@
|
|||
import socket, threading
|
||||
|
||||
class Networking:
|
||||
"""
|
||||
A class that contains common networking functions for both server and client.
|
||||
"""
|
||||
@staticmethod
|
||||
def recv_any_size(sock):
|
||||
"""
|
||||
Receives data from the socket without knowing the size of the data.
|
||||
|
||||
The sender must send the size of the data before sending the data.
|
||||
"""
|
||||
data_size = sock.recv(1024).decode()
|
||||
sock.send("OK".encode())
|
||||
data = sock.recv(int(data_size)).decode()
|
||||
return data
|
||||
|
||||
@staticmethod
|
||||
def send_any_size(sock, data):
|
||||
"""
|
||||
Sends data to the socket without knowing the size of the data.
|
||||
|
||||
Sends the size of the data before sending the data.
|
||||
"""
|
||||
sock.send(str(len(data)).encode())
|
||||
response = sock.recv(1024).decode()
|
||||
sock.send(data.encode())
|
||||
def recv_any_size(self, client):
|
||||
"""
|
||||
Receives data from the client without knowing the size of the data.
|
||||
|
||||
Client must send the size of the data before sending the data.
|
||||
"""
|
||||
data_size = client.recv(1024).decode()
|
||||
data = client.recv(int(data_size)).decode()
|
||||
return data
|
||||
|
||||
class Server:
|
||||
"""
|
||||
A basic server class that can be inherited to create a custom server.
|
||||
|
||||
Contains some basic networking functions.
|
||||
"""
|
||||
def __init__(self, host = "127.0.0.1", port = 8080):
|
||||
"""
|
||||
Hosts a basic server on the specified host and port
|
||||
"""
|
||||
self.host = host
|
||||
self.port = port
|
||||
self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
self.server.bind((self.host, self.port))
|
||||
|
||||
def start(self, max_connections = 5):
|
||||
"""
|
||||
Starts the server and listens for *max_connections* connections, defaulted to 5
|
||||
"""
|
||||
self.server.listen(max_connections)
|
||||
while True:
|
||||
client, addr = self.server.accept()
|
||||
print(f"Connection from {addr}")
|
||||
|
||||
# Start a new thread for the client
|
||||
threading.Thread(target=self.handle_client, args=(client,)).start()
|
||||
|
||||
def handle_client(self, client):
|
||||
"""
|
||||
Checks if the client sent "exit" and closes the connection if it did, else send the data back.
|
||||
|
||||
Overwrite with your own implementation.
|
||||
"""
|
||||
while True:
|
||||
data = self.recv(client)
|
||||
if data == "exit":
|
||||
break
|
||||
self.send(client, data)
|
||||
pass
|
||||
|
||||
def send(self, client, data):
|
||||
"""
|
||||
Sends data to the client
|
||||
"""
|
||||
Networking.send_any_size(client, data)
|
||||
|
||||
def recv(self, client):
|
||||
"""
|
||||
Receives data from the client
|
||||
"""
|
||||
return Networking.recv_any_size(client)
|
||||
|
||||
def stop(self):
|
||||
"""
|
||||
Stops the server
|
||||
"""
|
||||
self.server.close()
|
||||
|
||||
|
||||
class Client:
|
||||
"""
|
||||
A basic client class that can be inherited to create a custom client.
|
||||
|
||||
Contains some basic networking functions.
|
||||
"""
|
||||
def __init__(self, host = "127.0.0.1", port = 8080):
|
||||
"""
|
||||
Connects to a server on the specified host and port
|
||||
"""
|
||||
self.host = host
|
||||
self.port = port
|
||||
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
self.sock.connect((self.host, self.port))
|
||||
|
||||
def send(self, data):
|
||||
"""
|
||||
Sends data to the server
|
||||
"""
|
||||
Networking.send_any_size(self.sock, data)
|
||||
|
||||
def recv(self):
|
||||
"""
|
||||
Receives data from the server
|
||||
"""
|
||||
return Networking.recv_any_size(self.sock)
|
||||
|
||||
def close(self):
|
||||
"""
|
||||
Closes the connection
|
||||
"""
|
||||
Networking.send_any_size(self.sock, "exit")
|
||||
self.sock.close()
|
|
@ -0,0 +1,24 @@
|
|||
from networking import net_module
|
||||
import socket, threading
|
||||
|
||||
class Test_server(net_module.Server):
|
||||
def handle_client(self, client: socket.socket):
|
||||
print(self.recv(client))
|
||||
self.send(client, "Hello World")
|
||||
|
||||
print(self.recv(client))
|
||||
client.close()
|
||||
class Test_client(net_module.Client):
|
||||
def main(self):
|
||||
|
||||
self.send("Hello World")
|
||||
|
||||
print(self.recv())
|
||||
|
||||
self.close()
|
||||
|
||||
server = Test_server()
|
||||
threading.Thread(target=server.start, args=(1,)).start()
|
||||
client = Test_client()
|
||||
|
||||
client.main()
|
Loading…
Reference in New Issue