Skip to content

Instantly share code, notes, and snippets.

@mikebarkmin
Created July 31, 2019 11:54
Show Gist options
  • Save mikebarkmin/18e56fb7f4ec78670d0989d1f21f84e6 to your computer and use it in GitHub Desktop.
Save mikebarkmin/18e56fb7f4ec78670d0989d1f21f84e6 to your computer and use it in GitHub Desktop.
NRW Java-Classes in Python
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
/**
* <p>
* Materialien zu den zentralen NRW-Abiturpruefungen im Fach Informatik ab 2018
* </p>
* <p>
* Klasse Client
* </p>
* <p>
* Objekte von Unterklassen der abstrakten Klasse Client ermoeglichen
* Netzwerkverbindungen zu einem Server mittels TCP/IP-Protokoll. Nach
* Verbindungsaufbau koennen Zeichenketten (Strings) zum Server gesendet und von
* diesem empfangen werden, wobei der Nachrichtenempfang nebenlaeufig geschieht.
* Zur Vereinfachung finden Nachrichtenversand und -empfang zeilenweise statt,
* d. h., beim Senden einer Zeichenkette wird ein Zeilentrenner ergaenzt und beim
* Empfang wird dieser entfernt. Jede empfangene Nachricht wird einer
* Ereignisbehandlungsmethode uebergeben, die in Unterklassen implementiert werden
* muss. Es findet nur eine rudimentaere Fehlerbehandlung statt, so dass z.B.
* Verbindungsabbrueche nicht zu einem Programmabbruch fuehren. Eine einmal
* unterbrochene oder getrennte Verbindung kann nicht reaktiviert werden.
* </p>
*
* @author Qualitaets- und UnterstuetzungsAgentur - Landesinstitut fuer Schule
* @version 30.08.2016
*/
public abstract class Client
{
private MessageHandler messageHandler;
private class MessageHandler extends Thread
{
private SocketWrapper socketWrapper;
private boolean active;
private class SocketWrapper
{
private Socket socket;
private BufferedReader fromServer;
private PrintWriter toServer;
public SocketWrapper(String pServerIP, int pServerPort)
{
try
{
socket = new Socket(pServerIP, pServerPort);
toServer = new PrintWriter(socket.getOutputStream(), true);
fromServer = new BufferedReader(new InputStreamReader(socket.getInputStream()));
}
catch (IOException e)
{
socket = null;
toServer = null;
fromServer = null;
}
}
public String receive()
{
if(fromServer != null)
try
{
return fromServer.readLine();
}
catch (IOException e)
{
}
return(null);
}
public void send(String pMessage)
{
if(toServer != null)
{
toServer.println(pMessage);
}
}
public void close()
{
if(socket != null)
try
{
socket.close();
}
catch (IOException e)
{
/*
* Falls eine Verbindung getrennt werden soll, deren Endpunkt
* nicht mehr existiert bzw. ihrerseits bereits beendet worden ist,
* geschieht nichts.
*/
}
}
}
private MessageHandler(String pServerIP, int pServerPort)
{
socketWrapper = new SocketWrapper(pServerIP, pServerPort);
start();
if(socketWrapper.socket != null)
active = true;
}
public void run()
{
String message = null;
while (active)
{
message = socketWrapper.receive();
if (message != null)
processMessage(message);
else
close();
}
}
private void send(String pMessage)
{
if(active)
socketWrapper.send(pMessage);
}
private void close()
{
if(active)
{
active = false;
socketWrapper.close();
}
}
}
public Client(String pServerIP, int pServerPort)
{
messageHandler = new MessageHandler(pServerIP, pServerPort);
}
public boolean isConnected()
{
return(messageHandler.active);
}
public void send(String pMessage)
{
messageHandler.send(pMessage);
}
public void close()
{
messageHandler.close();
}
public abstract void processMessage(String pMessage);
}
import socket
from typing import Optional
from abc import ABC, abstractmethod
from threading import Thread
class Client(ABC):
"""
Objekte von Unterklassen der abstrakten Klasse Client ermoeglichen
Netzwerkverbindungen zu einem Server mittels TCP/IP-Protokoll. Nach
Verbindungsaufbau koennen Zeichenketten (Strings) zum Server gesendet und von
diesem empfangen werden, wobei der Nachrichtenempfang nebenlaeufig geschieht.
Zur Vereinfachung finden Nachrichtenversand und -empfang zeilenweise statt,
d. h., beim Senden einer Zeichenkette wird ein Zeilentrenner ergaenzt und beim
Empfang wird dieser entfernt. Jede empfangene Nachricht wird einer
Ereignisbehandlungsmethode uebergeben, die in Unterklassen implementiert werden
muss. Es findet nur eine rudimentaere Fehlerbehandlung statt, so dass z.B.
Verbindungsabbrueche nicht zu einem Programmabbruch fuehren. Eine einmal
unterbrochene oder getrennte Verbindung kann nicht reaktiviert werden.
"""
class MessageHandler(Thread):
class SockerWrapper():
def __init__(self, p_server_ip: str, p_server_port: int):
self._socket: Optional[socket.socket] = None
try:
self._socket = socket.socket(
socket.AF_INET, socket.SOCK_STREAM)
self._socket.connect((p_server_ip, p_server_port))
self._socket.setblocking(False)
except Exception:
pass
def receive(self) -> Optional[str]:
if self._socket is None:
return None
try:
line = ""
while True:
part = self._socket.recv(1)
if not part:
break
text = part.decode("utf-8")
if text != "\n":
line += text
elif text == "\n":
break
return line
except Exception:
return None
def send(self, p_message: str):
if self._socket is None:
return
try:
self._socket.sendall(p_message.encode("utf-8"))
except Exception:
pass
def close(self):
if self._socket is not None:
try:
self._socket.close()
except Exception:
pass
def __init__(self, p_server_ip: str, p_server_port: int, outer: 'Client'):
super().__init__()
self.__socket_wrapper = Client.MessageHandler.SockerWrapper(
p_server_ip, p_server_port)
self.__outer = outer
self._active = False
if self.__socket_wrapper._socket is not None:
self._active = True
self.start()
def run(self):
message = None
while self._active:
message = self.__socket_wrapper.receive()
if message is not None:
self.__outer.process_message(message)
else:
self.close()
def send(self, p_message: str):
if self._active:
self.__socket_wrapper.send(p_message)
def close(self):
if self._active:
self._active = False
self.__socket_wrapper.close()
def __init__(self, p_server_ip: str, p_server_port: int):
self.__message_handler = Client.MessageHandler(
p_server_ip, p_server_port, self)
def is_connected(self) -> bool:
return self.__message_handler._active
def send(self, p_message: str):
self.__message_handler.send(p_message)
def close(self):
self.__message_handler.close()
@abstractmethod
def process_message(self, p_message: str):
pass
/**
* <p>
* Materialien zu den zentralen NRW-Abiturpruefungen im Fach Informatik ab 2018
* </p>
* <p>
* Klasse Server
* </p>
* <p>
* Objekte von Unterklassen der abstrakten Klasse Server ermoeglichen das
* Anbieten von Serverdiensten, so dass Clients Verbindungen zum Server mittels
* TCP/IP-Protokoll aufbauen koennen. Zur Vereinfachung finden Nachrichtenversand
* und -empfang zeilenweise statt, d. h., beim Senden einer Zeichenkette wird ein
* Zeilentrenner ergaenzt und beim Empfang wird dieser entfernt.
* Verbindungsannahme, Nachrichtenempfang und Verbindungsende geschehen
* nebenlaeufig. Auf diese Ereignisse muss durch Ueberschreiben der entsprechenden
* Ereignisbehandlungsmethoden reagiert werden. Es findet nur eine rudimentaere
* Fehlerbehandlung statt, so dass z.B. Verbindungsabbrueche nicht zu einem
* Programmabbruch fuehren. Einmal unterbrochene oder getrennte Verbindungen
* koennen nicht reaktiviert werden.
* </p>
*
* @author Qualitaets- und UnterstuetzungsAgentur - Landesinstitut fuer Schule
* @version 30.08.2016
*/
import java.net.*;
import java.io.*;
public abstract class Server
{
private NewConnectionHandler connectionHandler;
private List<ClientMessageHandler> messageHandlers;
private class NewConnectionHandler extends Thread
{
private ServerSocket serverSocket;
private boolean active;
public NewConnectionHandler(int pPort)
{
try
{
serverSocket = new ServerSocket(pPort);
start();
active = true;
}
catch (Exception e)
{
serverSocket = null;
active = false;
}
}
public void run()
{
while (active)
{
try
{
//Warten auf Verbdinungsversuch durch Client:
Socket clientSocket = serverSocket.accept();
// Eingehende Nachrichten vom neu verbundenen Client werden
// in einem eigenen Thread empfangen:
addNewClientMessageHandler(clientSocket);
processNewConnection(clientSocket.getInetAddress().getHostAddress(),clientSocket.getPort());
}
catch (IOException e)
{
/*
* Kann keine Verbindung zum anfragenden Client aufgebaut werden,
* geschieht nichts.
*/
}
}
}
public void close()
{
active = false;
if(serverSocket != null)
try
{
serverSocket.close();
}
catch (IOException e)
{
/*
* Befindet sich der ServerSocket im accept()-Wartezustand oder wurde
* er bereits geschlossen, geschieht nichts.
*/
}
}
}
private class ClientMessageHandler extends Thread
{
private ClientSocketWrapper socketWrapper;
private boolean active;
private class ClientSocketWrapper
{
private Socket clientSocket;
private BufferedReader fromClient;
private PrintWriter toClient;
public ClientSocketWrapper(Socket pSocket)
{
try
{
clientSocket = pSocket;
toClient = new PrintWriter(clientSocket.getOutputStream(), true);
fromClient = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
}
catch (IOException e)
{
clientSocket = null;
toClient = null;
fromClient = null;
}
}
public String receive()
{
if(fromClient != null)
try
{
return fromClient.readLine();
}
catch (IOException e)
{
}
return(null);
}
public void send(String pMessage)
{
if(toClient != null)
{
toClient.println(pMessage);
}
}
public String getClientIP()
{
if(clientSocket != null)
return(clientSocket.getInetAddress().getHostAddress());
else
return(null); //Gemaess Java-API Rueckgabe bei nicht-verbundenen Sockets
}
public int getClientPort()
{
if(clientSocket != null)
return(clientSocket.getPort());
else
return(0); //Gemaess Java-API Rueckgabe bei nicht-verbundenen Sockets
}
public void close()
{
if(clientSocket != null)
try
{
clientSocket.close();
}
catch (IOException e)
{
/*
* Falls eine Verbindung getrennt werden soll, deren Endpunkt
* nicht mehr existiert bzw. ihrerseits bereits beendet worden ist,
* geschieht nichts.
*/
}
}
}
private ClientMessageHandler(Socket pClientSocket)
{
socketWrapper = new ClientSocketWrapper(pClientSocket);
if(pClientSocket!=null)
{
start();
active = true;
}
else
{
active = false;
}
}
public void run()
{
String message = null;
while (active)
{
message = socketWrapper.receive();
if (message != null)
processMessage(socketWrapper.getClientIP(), socketWrapper.getClientPort(), message);
else
{
ClientMessageHandler aMessageHandler = findClientMessageHandler(socketWrapper.getClientIP(), socketWrapper.getClientPort());
if (aMessageHandler != null)
{
aMessageHandler.close();
removeClientMessageHandler(aMessageHandler);
processClosingConnection(socketWrapper.getClientIP(), socketWrapper.getClientPort());
}
}
}
}
public void send(String pMessage)
{
if(active)
socketWrapper.send(pMessage);
}
public void close()
{
if(active)
{
active=false;
socketWrapper.close();
}
}
public String getClientIP()
{
return(socketWrapper.getClientIP());
}
public int getClientPort()
{
return(socketWrapper.getClientPort());
}
}
public Server(int pPort)
{
connectionHandler = new NewConnectionHandler(pPort);
messageHandlers = new List<ClientMessageHandler>();
}
public boolean isOpen()
{
return(connectionHandler.active);
}
public boolean isConnectedTo(String pClientIP, int pClientPort)
{
ClientMessageHandler aMessageHandler = findClientMessageHandler(pClientIP, pClientPort);
if (aMessageHandler != null)
return(aMessageHandler.active);
else
return(false);
}
public void send(String pClientIP, int pClientPort, String pMessage)
{
ClientMessageHandler aMessageHandler = this.findClientMessageHandler(pClientIP, pClientPort);
if (aMessageHandler != null)
aMessageHandler.send(pMessage);
}
public void sendToAll(String pMessage)
{
synchronized(messageHandlers)
{
messageHandlers.toFirst();
while (messageHandlers.hasAccess())
{
messageHandlers.getContent().send(pMessage);
messageHandlers.next();
}
}
}
public void closeConnection(String pClientIP, int pClientPort)
{
ClientMessageHandler aMessageHandler = findClientMessageHandler(pClientIP, pClientPort);
if (aMessageHandler != null)
{
processClosingConnection(pClientIP, pClientPort);
aMessageHandler.close();
removeClientMessageHandler(aMessageHandler);
}
}
public void close()
{
connectionHandler.close();
synchronized(messageHandlers)
{
ClientMessageHandler aMessageHandler;
messageHandlers.toFirst();
while (messageHandlers.hasAccess())
{
aMessageHandler = messageHandlers.getContent();
processClosingConnection(aMessageHandler.getClientIP(), aMessageHandler.getClientPort());
aMessageHandler.close();
messageHandlers.remove();
}
}
}
public abstract void processNewConnection(String pClientIP, int pClientPort);
public abstract void processMessage(String pClientIP, int pClientPort, String pMessage);
public abstract void processClosingConnection(String pClientIP, int pClientPort);
private void addNewClientMessageHandler(Socket pClientSocket)
{
synchronized(messageHandlers)
{
messageHandlers.append(new Server.ClientMessageHandler(pClientSocket));
}
}
private void removeClientMessageHandler(ClientMessageHandler pClientMessageHandler)
{
synchronized(messageHandlers)
{
messageHandlers.toFirst();
while (messageHandlers.hasAccess())
{
if (pClientMessageHandler == messageHandlers.getContent())
{
messageHandlers.remove();
return;
}
else
messageHandlers.next();
}
}
}
private ClientMessageHandler findClientMessageHandler(String pClientIP, int pClientPort)
{
synchronized(messageHandlers)
{
ClientMessageHandler aMessageHandler;
messageHandlers.toFirst();
while (messageHandlers.hasAccess())
{
aMessageHandler = messageHandlers.getContent();
if (aMessageHandler.getClientIP().equals(pClientIP) && aMessageHandler.getClientPort() == pClientPort)
return (aMessageHandler);
messageHandlers.next();
}
return (null);
}
}
}
import socket
from typing import Optional
from abc import ABC, abstractmethod
from threading import Thread, Lock
from list import List
class Server(ABC):
class NewConnectionHandler(Thread):
def __init__(self, p_port: int, outer: 'Server'):
super().__init__()
self.__server_socket = None
self._active = False
self.__outer = outer
try:
self.__server_socket = socket.socket(
socket.AF_INET, socket.SOCK_STREAM)
self.__server_socket.bind(("localhost", p_port))
self.__server_socket.listen(10)
self.__server_socket.setblocking(False)
self._active = True
self.start()
except Exception:
pass
def run(self):
while self._active:
try:
client_socket, _ = self.__server_socket.accept()
self.__outer.add_new_client_message_handler(client_socket)
self.__outer.process_new_connection(
client_socket.getsockname()[0],
client_socket.getsockname()[1]
)
except Exception:
pass
def close(self):
self._active = False
if self.__server_socket is not None:
try:
self.__server_socket.close()
except Exception:
pass
class ClientMessageHandler(Thread):
class ClientSocketWrapper():
def __init__(self, p_socket: socket.socket):
self.__client_socket = p_socket
self.__client_ip = p_socket.getsockname()[0]
self.__client_port = p_socket.getsockname()[1]
def receive(self) -> Optional[str]:
try:
line = ""
while True:
part = self.__client_socket.recv(1)
if not part:
break
text = part.decode("utf-8")
if text != "\n":
line += text
elif text == "\n":
break
return line
except Exception:
return None
def send(self, p_message: str):
self.__client_socket.sendall(p_message.encode("utf-8"))
def get_client_ip(self) -> str:
if self.__client_socket is not None:
return self.__client_ip
def get_client_port(self) -> int:
if self.__client_socket is not None:
return self.__client_port
def close(self):
if self.__client_socket is not None:
try:
self.__client_socket.close()
except Exception:
pass
def __init__(self, p_client_socket: socket.socket, outer: 'Server'):
super().__init__()
self.__socket_wrapper = Server.ClientMessageHandler.ClientSocketWrapper(
p_client_socket)
self.__outer = outer
self._active = False
if p_client_socket is not None:
self._active = True
self.start()
def run(self):
message = None
while self._active:
message = self.__socket_wrapper.receive()
if message is not None:
self.__outer.process_message(
self.__socket_wrapper.get_client_ip(),
self.__socket_wrapper.get_client_port(),
message
)
else:
a_message_handler = self.__outer.find_client_message_handler(
self.__socket_wrapper.get_client_ip(),
self.__socket_wrapper.get_client_port()
)
if a_message_handler is not None:
a_message_handler.close()
self.__outer.remove_client_message_handler(
a_message_handler
)
self.__outer.process_closing_connection(
self.__socket_wrapper.get_client_ip(),
self.__socket_wrapper.get_client_port()
)
def send(self, p_message: str):
if self._active:
self.__socket_wrapper.send(p_message)
def close(self):
if self._active:
self._active = False
self.__socket_wrapper.close()
def get_client_ip(self) -> str:
return self.__socket_wrapper.get_client_ip()
def get_client_port(self) -> int:
return self.__socket_wrapper.get_client_port()
def __init__(self, p_port: int):
self.__connection_handler = Server.NewConnectionHandler(p_port, self)
self.__message_handlers = List['Server.ClientMessageHandler']()
self.__message_handlers_lock = Lock()
def is_open(self) -> bool:
return self.__connection_handler._active
def is_connected_to(self, p_client_ip: str, p_client_port: int) -> bool:
a_message_handler = self.find_client_message_handler(
p_client_ip, p_client_port)
if a_message_handler is not None:
return a_message_handler._active
else:
return False
def send(self, p_client_ip: str, p_client_port: int, p_message: str):
a_message_handler = self.find_client_message_handler(
p_client_ip, p_client_port)
if a_message_handler is not None:
a_message_handler.send(p_message)
def send_to_all(self, p_message: str):
with self.__message_handlers_lock:
a_message_handler = None
self.__message_handlers.to_first()
while self.__message_handlers.has_access():
a_message_handler = self.__message_handlers.get_content()
if a_message_handler is not None:
self.process_closing_connection(
a_message_handler.get_client_ip(),
a_message_handler.get_client_port()
)
a_message_handler.close()
self.__message_handlers.remove()
def close_connection(self, p_client_ip: str, p_client_port: int):
a_message_handler = self.find_client_message_handler(
p_client_ip,
p_client_port
)
if a_message_handler is not None:
self.process_closing_connection(p_client_ip, p_client_port)
a_message_handler.close()
self.remove_client_message_handler(a_message_handler)
def close(self):
self.__connection_handler.close()
with self.__message_handlers_lock:
a_message_handler = None
self.__message_handlers.to_first()
while self.__message_handlers.has_access():
a_message_handler = self.__message_handlers.get_content()
self.process_closing_connection(
a_message_handler.get_client_ip(),
a_message_handler.get_client_port()
)
a_message_handler.close()
self.__message_handlers.remove()
@abstractmethod
def process_new_connection(self, p_client_ip: str, p_client_port: int):
pass
@abstractmethod
def process_message(self, p_client_ip: str, p_client_port: int, p_message: str):
pass
@abstractmethod
def process_closing_connection(self, p_client_ip: str, p_client_port: int):
pass
def add_new_client_message_handler(self, p_client_socket: socket.socket):
with self.__message_handlers_lock:
self.__message_handlers.append(
Server.ClientMessageHandler(p_client_socket, self)
)
def remove_client_message_handler(self, p_client_message_handler: 'Server.ClientMessageHandler'):
with self.__message_handlers_lock:
self.__message_handlers.to_first()
while self.__message_handlers.has_access():
if p_client_message_handler is self.__message_handlers.get_content():
self.__message_handlers.remove()
else:
self.__message_handlers.next()
def find_client_message_handler(self, p_client_ip: str, p_client_port: int) -> Optional['Server.ClientMessageHandler']:
a_message_handler = None
self.__message_handlers.to_first()
while self.__message_handlers.has_access():
a_message_handler = self.__message_handlers.get_content()
if a_message_handler.get_client_ip() == p_client_ip and \
a_message_handler.get_client_port() == p_client_port:
return a_message_handler
self.__message_handlers.next()
return None
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment