Client-Server-Kommunikation

HerrJemineh

Mitglied
Hallo liebes Java-Forum!

Da wir im nächsten Semester ein Client-Server basiertes Spiel programmieren müssen, wollte ich zum Einstieg versuchen ein Programm zu schreiben, sodass sich bis zu 5 Clients am Server verbinden und ein Viereck in einem Feld bewegen können. (Ohne Kollision oder andere Features)
Da ich in diesem Gebiet ein totaler Anfänger bin, habe ich mich an einem Tutorial orientiert, dies jedoch nicht 1:1 kopiert. Mein erstes Problem ist folgendes: Ich starte den Server (mit Port 8888) und verbinde dann einen Client mit gleichem Port, bekomme jedoch die Exception:"Address already in use: JVM_Bind"
Wenn ich unter der Eingabeaufforderung von Windows netstat -a eingebe, sehe ich jedoch dass dieser Port vorher nicht benutzt wurde, also muss der Fehler im Programm liegen (denke ich).
Es wäre sehr nett, wenn mir jemand meinen Fehler erklären würde, hier sind die Klassen:

Java:
 import java.net.*;
import java.io.*;

public class Server {
	
	static DataInputStream in;
	static DataOutputStream out;
	static ServerSocket serverSocket;
	static Socket socket;
	static Player[] players;
	
	public static void main(String[] args) throws Exception {
		// starte den server
		System.out.println("Starte Server...");
		serverSocket = new ServerSocket(8888);
		System.out.println("Server gestartet.");
		// nehme solange neue clients an, bis 5 verbunden sind
		while(true){
			Socket socket = serverSocket.accept();
			for(int i = 0; i < 5; i++){
				if(players[i] == null){
					System.out.println("Verbinde mit: " + socket.getInetAddress());
					out = new DataOutputStream(socket.getOutputStream());
					in = new DataInputStream(socket.getInputStream());
					players[i] = new Player(out, in, players, i);
					Thread th = new Thread(players[i]);
					th.start();
					break;
				}
			}
		}
	}


}

class Player implements Runnable{
	
	DataInputStream in;
	DataOutputStream out;
	Player[] players = new Player[5];
	int playerid;
	int playeridin;
	int xin;
	int yin;
	
	public Player(DataOutputStream out, DataInputStream in, Player[] players, int pid){
		this.out = out;
		this.in = in;
		this.players = players;
		this.playerid = pid;
	}

	public void run() {
		// gebe zuerst immer die playerID aus
		try{
			out.writeInt(playerid);
		} catch (IOException e1){
			System.out.println("Failed to send PlayerID");
		}
		// lese koordinaten des jeweiligen players ein und sende sie an alle anderen clients
		// damit diese sie zeichnen können
		while(true){
			try{
				playeridin = in.readInt();
				xin = in.readInt();
				yin = in.readInt();
				for(int i = 0; i < 5; i++){
					if(players[i] != null){
						players[i].out.writeInt(playeridin);
						players[i].out.writeInt(xin);
						players[i].out.writeInt(yin);
					}
				}
			} catch (IOException e){
				players[playerid] = null;
			}
		}

	}
	
	
}

und hier die Client-Klasse:

Java:
 import java.net.*;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.*;
import javax.swing.JFrame;
import javax.swing.JLabel;

public class Client extends MyFrame implements Runnable, KeyListener{
	
	static Socket socket;
	static DataInputStream in;
	static DataOutputStream out;
	int playerid;
	int x[] = new int[5];
	int y[] = new int[5];
	boolean up,down,right,left;
	int playerx, playery;
	MyFrame f;
	
	public void init(){
		// erstelle frame
		f = new MyFrame();
		f.setSize(600, 300);
		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		f.setResizable(false);
		f.setVisible(true);
		// füge keylistener hinzu, um tastatureingaben zu erkennen
		addKeyListener(this);
		// initialisierung des clients
		try{
		System.out.println("Verbinde...");
		socket = new Socket("localhost",8888);
		System.out.println("Verbunden.");
		in = new DataInputStream(socket.getInputStream());
		playerid = in.readInt();
		out = new DataOutputStream(socket.getOutputStream());
		Input input = new Input(in, this);
		Thread thread = new Thread(input);
		thread.start();
		Thread thread2 = new Thread(this);
		thread2.start();
		} catch(Exception e){
			System.out.println("Unable to start Client.");
		}
	}
	
	public void updateCoordinates(int pid, int x2, int y2){
		this.x[pid] = x2;
		this.y[pid] = y2;
	}

	public void run() {
		while(true){
			if(right) playerx += 10;
			if(up) playery -= 10;
			if(down) playery += 10;
			if(left) playerx -= 10;
			if(up||down||left||right){
				try {
					out.writeInt(playerid);
					out.writeInt(playerx);
					out.writeInt(playery);
				} catch (IOException e) {
					System.out.println("Error sending Coordinates.");
				}
			}
			f.repaintScreen();
			try {
				Thread.sleep(400);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

	public void keyPressed(KeyEvent e) {
		if(e.getKeyCode() == KeyEvent.VK_UP) up = true;
		if(e.getKeyCode() == KeyEvent.VK_RIGHT) right = true;
		if(e.getKeyCode() == KeyEvent.VK_DOWN) down = true;
		if(e.getKeyCode() == KeyEvent.VK_LEFT) left = true;
	}

	public void keyReleased(KeyEvent e) {
		if(e.getKeyCode() == KeyEvent.VK_UP) up = false;
		if(e.getKeyCode() == KeyEvent.VK_RIGHT) right = false;
		if(e.getKeyCode() == KeyEvent.VK_DOWN) down = false;
		if(e.getKeyCode() == KeyEvent.VK_LEFT) left = false;
	}

	@Override
	public void keyTyped(KeyEvent arg0) {}
}

class Input implements Runnable{
	
	DataInputStream in;
	Client client;
	
	public Input(DataInputStream in, Client c){
		this.in = in;
		this.client = c;
	}

	public void run() {
		while(true){
			try {
				int playerid = in.readInt();
				int x = in.readInt();
				int y = in.readInt();
				client.updateCoordinates(playerid, x, y);
			} catch (IOException e) {
				e.printStackTrace();
			}

		}
	}
	
}

Für eure Hilfe wäre ich sehr dankbar :)

lieben Gruß!
 

Highchiller

Bekanntes Mitglied
Kannst du mal den Stacktrace posten?

Und du sagst den Server kannst du normal starten aber sobald du den 1.(!!!) Client startest fliegt die Meldung?
 

HerrJemineh

Mitglied
Starte Server...
Exception in thread "main" java.net.BindException: Address already in use: JVM_Bind
at java.net.DualStackPlainSocketImpl.bind0(Native Method)
at java.net.DualStackPlainSocketImpl.socketBind(Unknown Source)
at java.net.AbstractPlainSocketImpl.bind(Unknown Source)
at java.net.PlainSocketImpl.bind(Unknown Source)
at java.net.ServerSocket.bind(Unknown Source)
at java.net.ServerSocket.<init>(Unknown Source)
at java.net.ServerSocket.<init>(Unknown Source)
at Server.main(Server.java:15)

Das ist die Ausgabe, die ich nach dem Starten des 1. Clients bekomme.
Mir ist gerade aufgefallen, dass wenn ich den Server starte, das "rote Stop-Kästchen" auch in der Client-Klasse aufleuchtet. Das darf doch eigentlich nicht sein, oder?

EDIT: "Starte Server..." sollte ja auch gar nicht ausgegeben werden. Vielleicht führe ich den Client gar nicht korrekt aus, aber wenn ich erst den Server mit Run as starte und dann bei Client auf Run as klicke, kommt nur Run Configurations
 
Zuletzt bearbeitet:

Tobse

Top Contributor
Port 8888 ist ein Standard-Port. Und wie die Fehlermeldung (selbstredend...) sagt, ist der Port schon in benutzung:
Code:
"Already in use"

Sprich: Benutze einen anderen Port. Hier findest du eine Liste aller standardisierten Ports, die du besser nicht verwenden solltest weil dir sonst der gleiche Fehler wieder und wieder passiert.
 

HerrJemineh

Mitglied
Ich habe es nun mal mit dem Port 8886 versucht, welcher auf der Liste nicht auftaucht, und habe trotzdem das gleiche Problem.
Den Server zu starten stellt ja auch kein Problem dar, d.h. der Port muss ja frei sein.
Woran kann es denn liegen, dass ich einfach den Client nicht starten kann?
Wie gesagt, wenn ich in der ClientKlasse den Cursor auf das grüne PlayZeichen bewege, kommt die Meldung "Run Server (already running)". Braucht der Client eine main, damit ich ihn ausführen kann?

EDIT: deswegen wahrscheinlich auch "already in use" weil ich den server 2 mal hintereinander starte
 
Zuletzt bearbeitet:

HerrJemineh

Mitglied
Ja, also ich bin mir mittlerweile auch sicher, dass der Fehler in der fehlenden main-Methode liegt. Wegen dieser habe ich fälschlicher Weise immer gedacht, ich würde durch "Play" drücken den Client starten, habe aber den Server ein zweites mal versucht zu starten und dann kam die Exception. Ich bräuchte dennoch eure Hilfe:

Wenn ich jetzt versuche eine main einzubauen, bekomme ich Probleme in Zeile 38 und 41, da ich "this" in einer statischen Methode nicht verwenden kann.

In dem Tutorial hat Client von Applet geerbt und man konnte Client auch ohne main runnen. Ich wollte es jedoch mit JFrames (MyFrame) implementieren und nicht mit Applet.

Wie gehe ich am besten vor?
 

Highchiller

Bekanntes Mitglied
Klassischer Fehler :) Eclipse halt, nur weil mans anwählt heißt das nicht das ers auch startet. Naja gut das wir das klären konnten.

Was das andere Problem angeht bin ich mir nicht sicher ob ich dich verstehe. Mach doch einfach:
Java:
public static void main(String[] args){
    Client client = new Client();
    client.init();
}

So startet man eigentlich immer Programme wenn man eine Klasse startet die eigene Main-Methoden besitzen. Außer man zielt darauf ab sowieso alles statisch zumachen was wohl nur zu Testzwecken Sinn macht :D

Aber irgendwie hab ich den verdacht darum gehts dir irgendwie nicht. Deine Zeilennummern sind übrigens anscheinend nicht mehr konsistent. Welche klasse willst du mit einer Main ausstatten?
 
Zuletzt bearbeitet:

HerrJemineh

Mitglied
Doch, genau das meinte ich. Peinlich, dass ich darauf nicht gekommen bin :bloed:
Naja, funktionieren tut das ganze zwar noch nicht, aber ich werde noch was basteln und mich morgen nochmal melden, wenn es nicht klappt.

VIELEN DANK FÜR DIE HILFE BIS HIER HIN!!! :)
 

HerrJemineh

Mitglied
Hallo nochmal! Also es funktioniert mittlerweile so wie ich es wollte. Ich habe nur eine kurze Frage:
Wenn ich jetzt möchte, dass ein Freund von mir sich mit meinem Server verbindet muss er ja die Klasse Client haben und anstatt localhost meine IP-Adresse eingeben, oder muss man noch mehr ändern?
Es klappt nämlich irgendwie nicht. Kann das auch an meiner Firewall liegen oder ähnlichem?

Vielen Dank!
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
G [Game-Multiplayer] Welt vom Server zum Client senden. Spiele- und Multimedia-Programmierung 0
c_sidi90 Server/Client Struktur Multiplayer Spiele- und Multimedia-Programmierung 9
M Browsergame Client Server Spiele- und Multimedia-Programmierung 4
F Meine Aufgabe: Client-Server am Beispiel einer Implementation eines Tic-Tac-Toe Netzwerkspieles Spiele- und Multimedia-Programmierung 7
T Selbst-handelnde Objekte im Client-Server Betrieb Spiele- und Multimedia-Programmierung 9
T Kartenspiel mit Server Client Funktionen Spiele- und Multimedia-Programmierung 3
R Client/Server Spiele- und Multimedia-Programmierung 5
ThoraxLaneus Minecraft MCP-Client mit Optifine fertig machen in IntelliJ klappt nicht ganz Spiele- und Multimedia-Programmierung 6
W Minecraft Client exportieren Spiele- und Multimedia-Programmierung 0
Z Minecraft Hilfe bei Minecraft PvP Client Spiele- und Multimedia-Programmierung 21
D JAVA Basiertes Spiel aus dem Internet in eigenem Client laden Spiele- und Multimedia-Programmierung 1
C Port umleiten: lesen und schreiben für MCServer-Client über Skype Spiele- und Multimedia-Programmierung 0
M Multiplayer Game mit Frontend auf HTML5 - ohne ständigen Client Request - Möglich?! Spiele- und Multimedia-Programmierung 12
L Client für ein Browsergame Spiele- und Multimedia-Programmierung 21
S Game Client für kleine Competition Spiele- und Multimedia-Programmierung 3
A Wie JAVA Webcam Client programmieren? Spiele- und Multimedia-Programmierung 11
S Minecraft Server Status Abfragen Spiele- und Multimedia-Programmierung 9
Lord_Joker Minecraft Server Bat error Spiele- und Multimedia-Programmierung 2
N Minecraft Frage für einen Minecraft Server Spiele- und Multimedia-Programmierung 2
Joris Minecraft Minecraft Java Server Spiele- und Multimedia-Programmierung 6
Shanic Minecraft Minecraft Forge Server "Falsche Java Version" Spiele- und Multimedia-Programmierung 6
JeremyStarTM Minecraft Minecraft Spigot Server akzeptiert JAR-Version nicht Spiele- und Multimedia-Programmierung 8
L Minecraft 1.7.10 Server startet nicht Spiele- und Multimedia-Programmierung 1
T Minecraft Minecraft-Server pingt lange Spiele- und Multimedia-Programmierung 3
G [Java Server] Allgemeine Frage zum Thema Networking in Videospielen Spiele- und Multimedia-Programmierung 15
ZoXlike Audio Server selbst erstellen Spiele- und Multimedia-Programmierung 11
U Minecraft Mit Java auf Minecraft Server anmelden Spiele- und Multimedia-Programmierung 11
A Minecraft Java Ubuntu Minecraft Server startet nicht - ERROR (SIGSEGV) Spiele- und Multimedia-Programmierung 7
R Minecraft Minecraft läuft nicht paralel mit minecraft server ? Spiele- und Multimedia-Programmierung 3
D Minecraft Spieleranzahl von Minecraft Server abfragen Spiele- und Multimedia-Programmierung 8
M Minecraft Bukkit Server VM Kann nicht Vergrößert werden Spiele- und Multimedia-Programmierung 20
C Minecraft Minecraft-Programm: Server anpingen Spiele- und Multimedia-Programmierung 2
Kr0e Red Dwarf Game Server Spiele- und Multimedia-Programmierung 5
R Minecraft Minecraft Server Spiele- und Multimedia-Programmierung 20
T Radio/TV-Server Spiele- und Multimedia-Programmierung 3
Dit_ Server Monitor [Quake III] Spiele- und Multimedia-Programmierung 20
A Visuell darstellen ob Server verfügbar Spiele- und Multimedia-Programmierung 2
G Server und java Spiele- und Multimedia-Programmierung 3

Ähnliche Java Themen

Neue Themen


Oben