# Grundlegendes Verständnis



## Thorsten F. (20. Nov 2006)

Hi, 
ich habe in Java ein 2-Personen-Spiel programmiert. Es funkioniert auch wunderbar, d.h. alle Regeln und Regelverstöße sind implementiert. Das Spiel läuft also fehlerfrei.

Jetzt möchte ich dieses gerne netzwerkfähig machen.

Frage 1: Benutzt man dafür ausschließlich Sockets um eine Verbindung herzustellen?
Frage 2: Auf beiden Rechner muss haargenau das gleiche Spiel laufen in Bezug auf Source Code: Also ich mache aus dem Projekt ein jar-File und dieses muss ich auf beiden Rechner starten.
Frage 3 (wahrscheinlich abhängig von Frage 2): Der Serverrechner ist nicht eindeutig, d.h. es kann also Rechner 1 einen Server aufmachen oder Rechner 2.  Welcher Rechner auch immer Server spielt, der andere muss sich connecten.
Frage 4: Der SourceCode muss einmal eine "Stelle" für Server beinhalten und einmal eine "Stelle" für Client. Wenn Rechner 1 jetzt Server ist, dann darf hier die Client-"Stelle" nicht angesprochen werden. Anders bei Rechner 2: Hier muss dann die Client-"Stelle" angesprochen werden und die Server-"Stelle" nicht.

Habe ich das alles so richtig verstanden oder verstehe ich etwas grundlegend falsch?

Wenn das alles so richtig ist, dann kommunizieren die Rechner doch nur über 2 Variablen: 
    1. wer ist dran?
    2. das aktuelle Spielfeld nach jedem Zug.

Richtig?

Wäre für Kommentare und Hilfe dankbar.

Gruß,
Thorsten F.


----------



## SlaterB (20. Nov 2006)

1.
gibt sicherlich noch anderes, aber Sockets sind durchaus ok,
ganz lowlevel zum übertragen einzelner String oder serialisierter Objekte

2.
was ist die Frage?
allgemein können beliebige Programme miteinander kommunizieren,
also auch verschiedene Versionen eines Programmes,
wenn z.B. nur Strings übertragen werden, kommt es nur darauf an, dass sich die Gegenseiten verstehen,

3.
der Serverrechner kann eindeutig sein oder auch nicht, ganz wie man will,
was ist die Frage?

4.
bisschen wirr formuliert, aber der Grundsatz dürfte klar sein,
wenn beide Programm als Server agieren passiert nicht viel,
wenn beide als Clienten nach Servern suchen werden beide nix finden,
also muss irgendwie einer Server und einer Client sein,
und dann natürlich den jeweils passenden Code verwenden


----------



## Thorsten F. (20. Nov 2006)

Hi,

würde das auch so gehen?

Ich erstelle aus dem gleichen Projekt einmal eine ClientVersion von dem Spiel und einmal eine Serverversion.
Damit meine ich, dass die ServerVersion eine zusätzliche Klasse beinhaltet, nämlich den SpielServer. Diese gibt dann einfach gewisse Variablen an die beiden Rechner weiter.

Einmal müsste die Serverklasse dann an localhost weiterleiten und einmal an den Rechner im Netzwerk, entweder per IP oder Rechnername.

Im Spiel: Der Spieler an dem Netzwerkrechner macht einen Zug. Das aktuelle Spielfeld wird an den Server gegeben und dieser gibt das dann an localhost weiter.
Der Spieler am localhost machen einen Zug und danacg wird das aktuelle Spielfeld wieder dem Server gegeben und dieser gibt das an den Netzwerkrechner weiter?

Kann man das so machen? Im Endeffekt läuft das darauf hinaus, das beide Recher die ClientVersion und die Serverversion von dem Spiel haben. Sie sprechen sich dann ab wer Server macht und daraufhin startet der eine die ServerVersion und der andere die ClientVersion.

Mit Teamspeak im LAN geht das auch so änhlich. Einer macht Server und die anderen starten lediglich den TS-Client.

Kann man das so machen oder zu aufwendig, also würde das anders wesentlich einfacher gehen?

Gruß,
Thorsten F.


----------



## SlaterB (20. Nov 2006)

man kann alles machen,
mach doch einfach irgendwas und dann läuft es?
oder berichte von den Problemen (besser aber vorher Tutorials anschauen)

auf jeden Fall sollte eine Version des Programmes reichen,
dann lieber per Parameter beim Start oder ähnliches die Funktion unterscheiden, 
evtl. eine  server.bat und eine client.bat-Datei (unter Windows) zum einfacheren Start

und das ganze Spielfeld zu übertragen erscheint mir überflüssig,
reicht doch eine Info wie 'Bauer G3 nach G4' beim Schach

----------

> Einmal müsste die Serverklasse dann an localhost weiterleiten und einmal an den Rechner im Netzwerk

so klingt das nach drei Programmen, dir fehlt noch die Erfahrung damit,
probiere das doch erstmal aus bevor du große Abläufe planst,

im allgemeinen (einfachsten Fall) IST der Server das localhost-Programm,
da gibts nix an localhost weiterzuleiten,

es sei denn du möchtest zwei identische Clients, die über einen dritten Server kommunizieren,
der auf einen der beiden Rechner sitzt, 
geht auch, ist vielleicht gar nicht dumm,


----------



## Thorsten F. (20. Nov 2006)

Hi,

so, ich habe es nun geschafft, dass sich die beiden Rechner bzw. die Java-Programme auf den Rechnern, miteinander unterhalten.

Allerdings muss ich erst den Server starten und dann den Client. Der Client gibt mir dann den String aus, den ich im Server gesetzt habe.
Danach geht aber nichts mehr.

Wie kann man das nun machen, dass der Server und der Client sich in Echtzeit unterhalten und dass die beiden sich solange unterhalten, bis ich den Server schließe?

Habe die Kommunikation von diesem Link:
http://www.cise.ufl.edu/~amyles/tcpchat/

Dort gibt es einmal eine Server.java und eine Client.java. Wie gesagt, das funkioniert auch soweit. 

Zu meinem Problem: Den Server habe ich in meinem Spiel eingebunden. Wenn ich dieses nun starte und anschließende auf ein Feld klicke (das Feld wird rot; das kommt vom Spiel), dann rufe ich den Server auf und dieser schickt die entsprechenden Koordinaten zum Client.

Danach starte ich den Client. Und siehe da, der Client bekommt die Koordinaten und setzt dem entsprechend bei sich das Feld auf rot. 
Nun habe ich beim Client und Server das gleiche Bild, was ja auch richtig ist.

Aber, das Ganze funktioniert nur einmal. Wenn ich danach beim Server nochmal auf ein Feld klicke, dann bekommt der Client davon nichts mit.

Könnte ich dieses Problem umgehen, wenn ich das Ganze auf dem Client in einem Thread mache, der sich nach einer bestimmten Zeit immer wieder aufruft?

Gruß,
Thorsten F.

PS: Netzwerkprogrammierung in Java ist Neuland für mich, deswegen bitte nicht böse sein, falls ich hier unwissend Müll erzähle. ^^


----------



## SlaterB (21. Nov 2006)

> dann rufe ich den Server auf und dieser schickt die entsprechenden Koordinaten zum Client. 

genauer: der Server wartet auf eine Verbindung, erst wenn sich ein Client bei ihm anmeldet, kann er die Daten losschicken

-----------

ohne Thread ist das ganze schnell vorbei, stimmt,

eine Stelle für einen Thread ist die Serverklasse,
diese könnte nach dem Aufbau einer Verbindung wiederum am Port lauschen, auf eine weitere Verbindung,
vielleicht bei dir erstmal nicht nötig, später unerlässlich wenn drei miteinander spielen

ein weiterer Grund, den Server in einen Thread zu stecken:
das Warten auf die Verbindung blockiert ansonsten das Hauptprogramm, 
z.B. dürfe deine GUI nix mehr machen wenn du den Socket in einem ActionListener oder so öffnest und sich noch kein Client angemeldet hat,
solange gewartet wird passier nix anderes

----------


davon unabhängig braucht man einen Thread für die Verbindung,
für den Inputstream eines Sockets, für das Empfangen der Daten,

z.B.

```
/*
	 * bearbeitet laufende Verbindung
	 */
	public void run() {
		int len;
		byte[] b = new byte[400];

		while (!breakConnection) {
			try {

				if ((len = in.read(b)) == -1) {
					break;
				}

				if (empf != null) {
					empf.verarbeiteDaten(new String(b, 0, len));
				}

			} catch (InterruptedIOException e) {
				//nochmal versuchen
			} catch (IOException e) {
				System.out.println("IO-Exception");
				e.printStackTrace();
			}

		}
	}
```

der auch nach einiger Zeit noch von empfangen Daten Notiz nimmt,
zum Senden ist ein Thread eher weniger nötig,
solange der OutputStream als Referenz ansprchbar ist, kann man da einfach was reinschreiben,

so, Mund ist fusselig, lies doch erstmal Grundlagen nach,
da gibts so viel zu beachten..


----------



## Thorsten F. (21. Nov 2006)

So, nachdem ich mir mal viele Beispiele im Netz angeschaut habe, wie man soetwas überhaupt angehen muss, habe ich es tatsächlich geschafft, das Spiel netzwerkfähig zu machen und siehe da: Alles läuft wunderbar.

Auch deine Antworten haben mir sehr weitergeholfen.

Gruß,
Thorsten F.

PS: Weiß nicht, wo ich das Thema als erledigt setzen kann.


----------



## Thorsten F. (21. Nov 2006)

Hi,

sorry für Doppelpostings, allerdings gehts das wahrscheinlich erst, wenn man sich hier angemeldet hat. Das habe ich auch gerade gemacht.
Habe jetzt ein neues Problem: Habe das mit Spiel auf beiden Rechnern ausgiebig getestet und es hat auch funkioniert.
Dann habe ich jars erstellt und auf einem Rechner den Server gestartet und auf dem anderen den Client. 
Jetzt geht allerdings gar nichts mehr. Ich sehe zwar die Spielfeld, aber wenn ich auf eins klicken, dann hängt das Spiel und ich muss es über dem TaskManager beenden.

Weiß jemand warum und wieso?


----------



## SlaterB (21. Nov 2006)

nur jars erstellt, nix verändert?
auf Windowsrechnern kann man mit 
netstats -a 
prüfen, welche Ports belegt sind,
arbeitet der Server?

mir fällt sonst nix ein, wenn du mir das jar/ die jars schickst, könnte ich testen
slaterb@gmx.de


----------



## Thorsten F. (21. Nov 2006)

Hi,
omg, ich bin vielleicht einer. Der Client startet beim Spiel zusätzlich ein Fenster in dem man den Hostnamen oder auch die Host-IP-Adresse eingeben kann.
Diese TextFeld habe ich eigentlich mit "PCName/IP-Adress" vorbelegt. Allerdings war ich da wohl zu schnell, denn beim genaueren Betrachten haben sich am Ende des Textes noch 2 Blanks eingeschlichen, die ich da wohl aus irgendeinem Grund hingemacht habe, also: "PCName/IP-Adress  ". Wenn ich jetzt den Text""PCName/IP-Adress" markiert habe, und die IP eingeben haben, dann sah die IP so aus:
"192.168.178.xx  ". Diese IP gibt es natürlich nicht. Das war auch schon alles.


----------

