Hallo,
ich möchte meine ersten Schritte in Server/Client Anwendungen machen.
Nun habe ich eine Idee bzw. eine passende Anwendung, wo es zum Einsatz kommen soll.
Leider habe ich noch einige Fragenm die ich nicht aus dem kopf kriegen, oder ich mach mir eventuell auch zu viele Gedanken! :autsch:
Die Anwendung soll so aussehen, dass in einem Verzeichnis verschiedene Ordner liegen. Jeder Ordner ist ein "JOB". Die Daten aus diesem sogenannten Job müssen auf 3 Webserver kopiert werden (sind alle im LAN) und auf einen FTP Server. Der Server muss hier wissen, welche Jobs vorhanden sind und muss diese bei einer Anemldung des Clients an diesen versenden.
Die verschiedenen Clients haben nun die Möglichkeit, Jobs anzulegen, löschen und uploaden. Bei allen Aktionen muss jeweils ein Job und eine Message an den Server übergeben werden, welcher Job und welche Aktion ausgeführt werden soll. Weiter müssen die Messages/Aktionen "QUIT", UPDATE (hier soll der Client die neue Liste der Jobs erhalten) ausführbar sein.
Soweit ist das meine Theorie.
Ich habe mich nun in ServerSocket und Sockets eingelesen und auch verstanden würde ich behaupten. Sind ServerSocket und Socket eigentlich das richtige für diese Anwendung? Habe jetzt auch mal weiter geforscht und dann ist mir das Framework Netty aufgefallen. Da bin ich mir nicht sicher, da ich damit noch nie was gemacht habe bzw. es noch nie gehört habe. Meine Anfänge der Programmierung sehen so aus.
Dazu habe ich ein Protokoll bzw. einen Command geschrieben, denen beider bekannt ist. Aber ich finde der ist noch zu kompliziert, der enhtält auch noch nicht alles. Wie gesagt, ich bin mir da nicht sicher, ob es der richtige Ansatz ist. Dazu der Code.
Wie oben schon egsagt, bin ich mir überhaupt nicht sicher ob es der richtige Ansatz ist, wie sich die Clients unterhalten sollen. gibt es dort eventuell andere/bessere Wege, wie ich es umsetzen könnte?
Ich würde mich freuen, wenn ihr mir dort etwas Licht in die dunklen stellen bringt, eventuell tut es auch eifnach mal gut darüber zu schreiben, denn irgendwie komme ich nicht weiter und stehe schon länger auf der Stelle ???:L
Wenn noch Fragen sind beantworte ich diese recht schnell.. Hoffe das wir dort eine Lösung finden.. :rtfm:
Gruß
Ollek
ich möchte meine ersten Schritte in Server/Client Anwendungen machen.
Nun habe ich eine Idee bzw. eine passende Anwendung, wo es zum Einsatz kommen soll.
Leider habe ich noch einige Fragenm die ich nicht aus dem kopf kriegen, oder ich mach mir eventuell auch zu viele Gedanken! :autsch:
Die Anwendung soll so aussehen, dass in einem Verzeichnis verschiedene Ordner liegen. Jeder Ordner ist ein "JOB". Die Daten aus diesem sogenannten Job müssen auf 3 Webserver kopiert werden (sind alle im LAN) und auf einen FTP Server. Der Server muss hier wissen, welche Jobs vorhanden sind und muss diese bei einer Anemldung des Clients an diesen versenden.
Die verschiedenen Clients haben nun die Möglichkeit, Jobs anzulegen, löschen und uploaden. Bei allen Aktionen muss jeweils ein Job und eine Message an den Server übergeben werden, welcher Job und welche Aktion ausgeführt werden soll. Weiter müssen die Messages/Aktionen "QUIT", UPDATE (hier soll der Client die neue Liste der Jobs erhalten) ausführbar sein.
Soweit ist das meine Theorie.
Ich habe mich nun in ServerSocket und Sockets eingelesen und auch verstanden würde ich behaupten. Sind ServerSocket und Socket eigentlich das richtige für diese Anwendung? Habe jetzt auch mal weiter geforscht und dann ist mir das Framework Netty aufgefallen. Da bin ich mir nicht sicher, da ich damit noch nie was gemacht habe bzw. es noch nie gehört habe. Meine Anfänge der Programmierung sehen so aus.
Java:
//Der Server
public class Server {
private Config config = Config.getInstance();
private Log4JLogger logger = Log4JLogger.getInstance();
private Hashtable outputStreams = new Hashtable();
private Map<Socket, ObjectOutputStream> clientOutputStreams;
private ServerSocket serverSocket;
private Scheduler sched;
public void listen(){
try {
clientOutputStreams = Collections.synchronizedMap(new HashMap<Socket, ObjectOutputStream>());
serverSocket = new ServerSocket(Integer.parseInt(config.getProperty("network.socket.port")));
System.out.println("Server gestartet auf " + serverSocket.getInetAddress().getHostAddress() + ":" + serverSocket.getLocalPort());
String timeout = config.getProperty("network.socket.timeout");
if(!timeout.equalsIgnoreCase("never")) {
serverSocket.setSoTimeout(Integer.parseInt(timeout));
}
while(true){
Socket socket = serverSocket.accept();
System.out.println("Verbunden mit " + socket.getInetAddress().getHostAddress());
ObjectOutputStream oOut = new ObjectOutputStream(socket.getOutputStream());
clientOutputStreams.put(socket, oOut);
new ServerThread(this, socket, oOut);
}
} catch (NumberFormatException e) {
logger.log(Level.ERROR, this.getClass(), "Servern konnte nicht auf dem Port gestartet werden...", e);
System.exit(1);
} catch (IOException e) {
logger.log(Level.ERROR, this.getClass(), "ServerSocket konnte nicht gestartet werden. da er schon läuft", e);
System.exit(1);
}
try {
serverSocket.close();
} catch (IOException e) {
logger.log(Level.ERROR, this.getClass(), "ServerSocket konnte nicht geschlossen werden.", e);
System.exit(1);
}
}
/**
* Sendet das übergebene Objekt an alle
* verbundenen Clients
*
* @param object
*/
public void sendToAll(JobCommand command){
Set<Socket> set = clientOutputStreams.keySet();
synchronized (clientOutputStreams) {
Iterator<Socket> iterator = set.iterator();
while(iterator.hasNext()){
Socket socket = iterator.next();
ObjectOutputStream oos = clientOutputStreams.get(socket);
try {
oos.writeObject(command);
oos.flush();
} catch (IOException ex) {
logger.log(Level.ERROR, this.getClass(), "Probleme beim Senden des Jobs an die Clients", ex);
}
}
}
}
/**
* Socketverbindung wird getrennt
*
* @param socket - zu trennendes Socket
*/
public void removeConnection(Socket socket) {
synchronized (clientOutputStreams) {
try {
System.out.println("Trenne Verbindung zum Client " + socket.getInetAddress());
clientOutputStreams.remove(socket);
socket.close();
System.out.println("Erfolgreich getrennt! Client " + socket.getInetAddress());
} catch (IOException e) {
logger.log(Level.ERROR, this.getClass(), "Konnte die Verbindung zum Client-Socket nicht schließen", e);
}
}
}
}
// Der server Thread, für jeden angemeldeten Client
public class ServerThread extends Thread {
private Log4JLogger logger = Log4JLogger.getInstance();
private Socket socket;
private Server server;
private FileIO fileIO;
private ObjectOutputStream oOut;
public ServerThread(Server server, Socket socket, ObjectOutputStream oOut){
this.socket = socket;
this.server = server;
this.oOut = oOut;
// Thread starten
start();
}
@Override
public void run() {
fileIO = new FileIO();
boolean isRunning = true;
try {
ObjectInputStream oIn = new ObjectInputStream(socket.getInputStream());
JobCommand commandFromClient;
while((commandFromClient = (JobCommand) oIn.readObject()) != null){
JobCommand commandToClient = new JobCommand();
commandToClient.setMessage("reload");
oOut.writeObject(commandToClient);
oOut.flush();
if(commandFromClient != null){
boolean result = false;
// if( commandFromClient.getMessage().equals("upload") && commandFromClient.getJob() != null){
// System.out.println("ServerThread.run() - UPLOAD");
// Upload upload = new Upload();
// boolean result = upload.upload(commandFromClient.getJob());
// if(result){
// commandToClient.setMessage("reload");
// }
if( commandFromClient.getMessage().equals("quit") && commandFromClient.getJob() != null){
oIn.close();
commandToClient.setMessage("quit");
oOut.writeObject(commandToClient);
oOut.flush();
isRunning = false;
System.out.println("ServerThread.run() - QUIT");
break;
}
// if( commandFromClient.getMessage().equals("delete") && commandFromClient.getJob() != null){
// System.out.println("ServerThread.run() - DELETE");
// result = fileIO.deleteDirectory(commandFromClient.getJob().getSourceDirectory());
// commandToClient.setMessage("reload");
// System.out.println("LÖSCHRESULT: " + result);
// logger.log(Level.INFO, this.getClass(), commandFromClient.getJob().getName() + " wurde erfolgreich gelöscht!");
// } else if( commandFromClient.getMessage().equals("reload")){
// System.out.println("ServerThread.run() - RELOAD");
// commandToClient.setMessage("reload");
// }
if(result){
logger.log(Level.INFO, this.getClass(), "MESSAGE to Clients");
server.sendToAll(commandToClient);
}
}
}
} catch (IOException e) {
logger.log(Level.ERROR, this.getClass(), "Der Job wurde nicht verarbeitet", e);
} catch (ClassNotFoundException e) {
logger.log(Level.ERROR, this.getClass(), "Die Klasse des Commands wurde nicht gefunden", e);
}finally {
server.removeConnection(socket);
}
}
public void close() throws IOException{
oOut.close();
socket.close();
}
private JobCommand getDataFromClient( ObjectInputStream oIn ) throws IOException {
JobCommand commandFromClient = null;
while ( commandFromClient == null ){
try {
commandFromClient = (JobCommand) oIn.readObject();
} catch ( ClassNotFoundException e ) {
logger.log(Level.ERROR, this.getClass(), "Konnte den Command nicht finden", e);
}
}
System.out.println( "Get: " + commandFromClient.getMessage() );
return commandFromClient;
}
public Socket getSocket() {
return socket;
}
}
// Der Client
public class Client implements Runnable{
private Config config = Config.getInstance();
private Log4JLogger logger = Log4JLogger.getInstance();
private Socket clientSocket;
private ObjectOutputStream oOut;
private ObjectInputStream oIn;
private JobController controller;
public Client(JobController controller){
this.controller = controller;
connect();
}
/**
* Verbindet das Socket mit dem
* ServerSocket
*/
public void connect(){
try {
clientSocket = new Socket(config.getSocketHost(), config.getServerPort());
oOut = new ObjectOutputStream(clientSocket.getOutputStream());
oIn = new ObjectInputStream(clientSocket.getInputStream());
controller.setFrametitle(clientSocket.getInetAddress().getHostAddress());
new Thread(this).start();
} catch (UnknownHostException e) {
logger.log(Level.ERROR, this.getClass(), "Host konnte nicht gefunden werden.", e);
e.printStackTrace();
} catch (IOException e) {
logger.log(Level.ERROR, this.getClass(), "Konnte nicht mit dem Host verbunden werden.", e);
}
}
/**
* Schickt einen Command an den Server
*
* @param job
*/
public void sendCommandToServer(JobCommand commandToServer){
if(clientSocket.isConnected()){
try {
System.out.println("Client.processJob()");
oOut.writeObject(commandToServer);
oOut.flush();
} catch (IOException e) {
logger.log(Level.ERROR, this.getClass(), "Job konnte nicht an den Server geschickt werden", e);
}
}
}
/**
* Schließ die Input- und OutputStream
* und die Verbindung zum Socket
*/
public void close(){
try {
oIn.close();
oOut.close();
clientSocket.close();
} catch (IOException e) {
logger.log(Level.ERROR, this.getClass(), "Probleme beim Schließen der Verbindung zum Server", e);
}
}
/**
* Thread um Sendungen vom Server
* anzunehmen und abzuarbeiten
*/
public void run(){
boolean running = true;
while(running){
System.out.println("Client.run() - while()");
try {
JobCommand commandFromServer = (JobCommand) oIn.readObject();
if(commandFromServer.getMessage().equals("reload")){
System.out.println("Client.run()");
logger.log(Level.INFO, this.getClass(), "Client.run() - RELOAD");
// controller.updateJobList();
}
} catch (IOException e) {
logger.log(Level.ERROR, this.getClass(), "Der Job konnte nicht verarbeitet werden.", e);
running = false;
} catch (ClassNotFoundException e) {
logger.log(Level.ERROR, this.getClass(), "Der Job konnte nicht verarbeitet werden.", e);
running = false;
} finally {
if(clientSocket != null){
close();
}
}
}
}
}
Dazu habe ich ein Protokoll bzw. einen Command geschrieben, denen beider bekannt ist. Aber ich finde der ist noch zu kompliziert, der enhtält auch noch nicht alles. Wie gesagt, ich bin mir da nicht sicher, ob es der richtige Ansatz ist. Dazu der Code.
Java:
public class JobCommand implements Serializable {
private static final long serialVersionUID = -4055034871844633242L;
private Job job;
private String message;
public JobCommand(){
this.setMessage("");
this.setJob(null);
}
public String getMessage(){
return this.message;
}
public void setMessage(String command) {
this.message = command;
}
public Job getJob() {
return job;
}
public void setJob(Job job) {
this.job = job;
}
}
Wie oben schon egsagt, bin ich mir überhaupt nicht sicher ob es der richtige Ansatz ist, wie sich die Clients unterhalten sollen. gibt es dort eventuell andere/bessere Wege, wie ich es umsetzen könnte?
Ich würde mich freuen, wenn ihr mir dort etwas Licht in die dunklen stellen bringt, eventuell tut es auch eifnach mal gut darüber zu schreiben, denn irgendwie komme ich nicht weiter und stehe schon länger auf der Stelle ???:L
Wenn noch Fragen sind beantworte ich diese recht schnell.. Hoffe das wir dort eine Lösung finden.. :rtfm:
Gruß
Ollek