Zum Inhalt springen

asynchrone Clientverbindung


Timberwolf

Empfohlene Beiträge

Moin Moin,

ich habe ein kleines Problem mit der entiwcklung einer asynchronen Socketverbindung.

Hier erstmal die Grundlage dessen was ich damit vorhabe:

Ziel ist es eine Klasse zu schreiben die x Verbindungen zu x verschiendenen Server aufrecht erhält. Bei dem Server handelt es sich um einen Crysis Dedicated Game Server. Dieser verfügt über einen eigenen kleinen HTTP - Server.

Das problem an der ganzen sache ist aber das ich mir nicht sicher bin ob die daten die ich im gebe auch beim Server ankommen.

Eine Verbindung bekomme ich ohne weiteres nur der rest funktioniert anscheindent nicht.

hier seht ihr meine classConnection

public classConnection(String serverip, Integer serverport, String pwd){

		adr = serverip;

		p = serverport;

		pass = pwd;

		run();

	}


	public void run(){

		System.out.println("vor dem eigentlichen run");

		SocketChannel sc = null;

		Charset std = Charset.forName("utf-8");

		try {

			InetSocketAddress isa = new InetSocketAddress(InetAddress.getByName(adr), p);

			ByteBuffer bb = ByteBuffer.allocate(4096);


			sc = SocketChannel.open();

			Socket client = sc.socket();

			client.connect(isa,p);


			System.out.println("connect: "+ client.getRemoteSocketAddress());

			Integer result = sc.write(std.encode("<?xml version=\"1.0\" encoding=\"UTF-8\"?><methodCall><methodName>g_revivetime 10</methodName><params/></methodCall>"));

			System.out.println("write 1:" +result);


			if(sc.read(bb) != -1){

				System.out.println("if");

				bb.flip();

				String str = std.decode(bb).toString();

				System.out.println(str);

			}

			client.close();

			System.out.println("nach dem close");




		} catch (UnknownHostException e) {

			// TODO Auto-generated catch block

			e.printStackTrace();

		} catch (IOException e) {

			// TODO Auto-generated catch block

			e.printStackTrace();

		}

	}

Ich würde mich freuen wenn jemand von euch ne idee hat wie man das besser gestallten kann oder ob ich da irgendwo nen Fehler eingebaut habe und ihn aufgrund von Codeblindheit einfach nicht sehe.

Danke für die Hilfe und Gruß

Timberwolf

PS: wenn weitere Infos benötigt werden ist das kein Problem :)

Link zu diesem Kommentar
Auf anderen Seiten teilen

Was mir als erstes auffällt, ist "public classConnection". Aber das ist wohl mittlerweile behoben, da meckert der Compiler ja.

Also, wenn ich dich richtig verstanden habe, dann hast du eine Haupt-Applikation, die die Connection benötigt, um Zeugs aus dem Dediccated Server zu holen.

Schau dir mal das Beispiel hier an... ist ein guter Start dafür, um JAva-Netzwerk-

Clients zu bauen:

KnockKnockClient

Naja... und sonst ist bisschen mehr Info nicht schlecht. Ein Listing der aufrufenden Klasse usw.

PAX

Link zu diesem Kommentar
Auf anderen Seiten teilen

public classConnection ist der Kontruktor.

Was client / Server verbindungen angeht bin ich nicht ganz unbewandert.

Das problem was ich habe ist das ich nicht bestätigen kann das der Server den jeweiligen Befehl erhalten und auch ausgeführt hat, da ich nicht verifizieren kann das ich was vom Server zurück bekomme.

Es wird bestätigt das ich mit dem Server verbunden bin. mehr aber auch leider nicht.

die Klasse wird von einem JInternalFrame aufgerufen das die Daten die hier zurück kommen benötigt um diese darzustellen.

Link zu diesem Kommentar
Auf anderen Seiten teilen

rein theoretisch ja... ich habe das kleine problem das ich den Inputstream vom Socket nicht gelesen komme... nicht weil ich nciht weis wie sindern weil das tool aus mir unerfindlichen gründen einfriert... und das genau in dem augenblick wo ich versuche den InputStream zu lesen.

Der Server stellt eine XML/PRC Schnittstelle zur verfügung die ich nicht richtig bedient bekomme. daher vermute ich das ich da einen fehler mache...

so sieht der XML - Code aus den ich da rüber schicke..

<?xml version="1.0" encoding="UTF-8"?>

<methodCall>

<methodName>rcon_connect</methodName>

<params><param>

<value><string>addr:xxxxx</string></value>

</param>

<param>

<value><string>port:46964</string></value>

</param>

<param>

<value><string>pass:xxxx</string></value>

</param>

<param>

<value><string>connection_distributed 0</string></value>

</param>

</params>

</methodCall>

wenn ich heute abend dazu komme dann poste ich hier den Code den Ihr braucht um das einmal komplett nach zu arbeiten...

Link zu diesem Kommentar
Auf anderen Seiten teilen

rein theoretisch ja... ich habe das kleine problem das ich den Inputstream vom Socket nicht gelesen komme... nicht weil ich nciht weis wie sindern weil das tool aus mir unerfindlichen gründen einfriert...

Ich würde da folgendes probieren: Schreib Dir mal ein kleines Testprogramm, also genau eine Klasse mit "static int void main" und schick mal die Daten an den Dienst und versuche die Antwort zu erhalten.

Bei einer asychronen Verbindung würde ich das so machen:

Daten rausschicken und dann innerhalb eines Thread prüfen ob Daten da sind, wenn nicht Thread für eine gewisse Zeit schlafen legen. Im Thread läuft halt eine Schleife die den Socket abfragt ob Daten da sind. Wenn Du keine Daten sendest, deaktivierst Du einfach den Thread.

Evtl wäre es sinnvoll, wenn Du zu Beginn eine synchrone Verbindung benutzt um erst einmal das generell zum laufen zu bekommen.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Das mit der synchronen verbindung hatte ich auch schon versucht. da lief es aber genauso.

Ich werde mir gleich mal das kleine testtool schreiben und schauen was dabei rauskommt.

Wenn ich die Daten an den Port 8080 schicke auf dem der Http Server(CryHttp) läuft bekomme ich mit XML/RPC ein BadRequest.... wenn ich es aber mit einem XML - Debugger an den Rcon port schicke gibt es nur nen Url fehler(http://xxxIPxxx)

werde dann gleich mal berichten wie es lief....

Link zu diesem Kommentar
Auf anderen Seiten teilen

hier mal das kleine testtool.

System.out.println() gibt mir zweimal 24 Bytes... da hört es dann bei mir jetzt gerade einfach mal auf :)

public class testmain {


	/**

	 * @param args

	 */

	public static void main(String[] args) {

		String addr = "87.106.32.16";

		Integer port = 8080;

		Integer rconport = 46964;

		SocketChannel sc = null;

		Charset std = Charset.forName("utf-8");

		try {

			InetSocketAddress isa = new InetSocketAddress(InetAddress.getByName(addr), 46964);

			System.out.println(isa);

			ByteBuffer bb = ByteBuffer.allocate(4096);

			String msg = "<?xml version=\"1.0\"?>"+

							"<methodCall>"+

								"<methodName>rcon_command</methodName>"+

									"<params><param>"+

										"<value><string>sv_status</string></value>"+

								"</param></params>"+

							"</methodCall>";


			sc = SocketChannel.open();

			Socket client = sc.socket();

			client.connect(isa);


			System.out.println("connect: "+ client.getRemoteSocketAddress());

			DataInputStream is = new DataInputStream(client.getInputStream());

			DataOutputStream os = new DataOutputStream(client.getOutputStream());


			while(is.readByte() != 0){

				System.out.println(is.readByte());

			}

			for (int n=0; n<20; n++){

			  bb = std.encode(CharBuffer.wrap(msg));

			  sc.write(bb);

			  if(bb == null){

				System.out.println("Buffer ist leer");  

			  }

			  System.out.println(std.decode(bb));

			  bb.rewind();

			}

			client.close();

			System.out.println("nach dem close");


		} catch (UnknownHostException e) {

			// TODO Auto-generated catch block

			e.printStackTrace();

		} catch (IOException e) {

			// TODO Auto-generated catch block

			e.printStackTrace();

		}

	}

}

das ist alles was ich hab durchlaufen lassen. Wenn Ihr eine bessere Testlösung oder noch ne idee habt wie ich rausbekomme was mir da übergeben wird schiesst einfach los :)

werde selber noch weiter testen und schauen das ich das irgendwie gelöst bekomme.... danke schonmal für eure Hilfe.

grüsse Timberwolf

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ich hab mal auf die Schnelle nach diesem Tutorial Creating a Non-Blocking Socket | Example Depot die Verbindung herzustellen.

Auf Port 46964 kann ich nicht connecten, da ein "Connection refused" kommt. Auf 8080 kann ich connecten (via Telnet), erhalte aber, wenn ich Deine XML Daten versende:

HTTP/1.1 501 Not Implemented

Server: CryHttp/0.0.1

Content-Type: text/html

Content-Length: 56


<HTML><HEAD><TITLE>Not Implemented</TITLE></HEAD></HTML>

Wichtig bei den Socketchannels ist, dass Du prüfst, bevor Du die Daten schreibst, ob der Socket bereit ist. Das muss rein, es dauert bei mir ein paar Sekunden, bis die Verbindung steht.

Link zu diesem Kommentar
Auf anderen Seiten teilen

So... nach dem ich jetzt mehrere Stunden damit zugebracht habe die verschiedenen Beispiele im Tutorial durch zu kauen bin ich trotzdem leider zu keinem brauchbaren ergebnis gekommen.

Ich sehe zwar auf dem Server das da was passiert...also das der Server mich annimmt aber nicht das irgendwas zurück kommt.

Bin ja mal ganz ehrlich das ich das mit dem auslesen des ByteBuffers nicht so ganz kapiert habe...und ich denke mal das wenn der rückgabe wert des SocketChannels 0 ist hat der Server den entsprechenden befehl nicht ausgeführt bzw. liefert mir einfach nichts zurück. :)

muss mich korrigieren... hab das eben nochmal getestet und nu bekomm ich einen Intwert von 156 zurück....

wie meinst du das mit dem Thread und der while schleife... beides hab ich nicht in meinem testtool ja nu nicht drin

grüße

Link zu diesem Kommentar
Auf anderen Seiten teilen

Er meint, dass du am Besten mal ein Runnable implementierst und dann erstellt du in deiner Main-Klasse einen Thread, dem übergibst du dieses Runnable und startest es. Das frägt den Server nach Daten ab und diese werden dann in dein Socket geschrieben. Solange die Daten vom Server ins Socket geschrieben werden, legst du den Thread schlafen bzw. legst ihn in den Thread-Pool. Das kannst du mit einem if in einem try-catch-Block machen:

try{

//if (datenVorhanden){

System.out.println ("geiel");

}

catch (InterruptedException ie){

Thread.sleep (500);

}

Nun werden die Daten übertragen und alle halben Sekunden geht dein Thread schnell fragen, ob nun die Daten alle vorhanden sind. Wenn ja, gehz weiter in deinem Programm: Verarbeitung usw.

PS: Mir ist, als haben ByteBuffers noch eine flush()-Methode, die man benutzen muss, um den Inhalt einem StreamReader oder so weiterzugeben. Schau mal in der Doku nach... Das könnte auch noch ein Problem darstellen.

PAx

Link zu diesem Kommentar
Auf anderen Seiten teilen

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...