Zum Inhalt springen
View in the app

A better way to browse. Learn more.

Fachinformatiker.de

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Problem bei DatagramPacket.getData()

Empfohlene Antworten

Veröffentlicht

Ich muss schon wieder was loswerden :/

Es geht immernoch um meinen Client und meinen Server, die über UDP Pakete verschicken sollen. Mein Client erstellt das DatagramPacket ohne Probleme. Wenn ich den Dateinamen, den ich zum Test wieder in ein byte umwandle, die Länge des Namen berechne und ihn mir raushole und ausgeben lasse, dann bekomme ich "Testdatei" ausgegeben. So soll es sein. Nun schicke ich das Paket los ( nur auf localhost ) und mein Server bekommt es auch. Zunächst mal der nötige Code.

Client:


DatagramSocket clientsock = new DatagramSocket(); // UDP-Socket für Client
int port = Integer.parseInt(args[1]);

long filesize = new File( args[2] ).length() ; // Dateigröße in Bytes

byte[] StartByte;


// noch als Funktion auslagern
byte[] buf=new byte[8];
for(int i=0;i<8;i++){
buf[i]=(byte) (filesize>>>(i<<3));// Little Endian
}

System.out.println("Filename-size : "+ filesize );
System.out.println("Größe für dessen byte : " + buf.length );


StartByte = CombineBytes(args[2].getBytes(), args[2].getBytes().length, buf);
int crc = crc16( StartByte ); // crc-Wert holen
byte[] crcbyte = intToByte(crc);

StartByte = CombineBytes(StartByte, StartByte.length, crcbyte);

/* ****** bytes und int für Antwortpakete ****** */
byte[] receiveStartData = new byte[8];
byte[] ServerPort = new byte[4];
byte[] ServerCrc = new byte[4];
int newPort;

byte[] sendData = new byte[1024]; // bytes für Datenübertragung

/* ******************************************** */

clientsock.setSoTimeout(timeout);

// Paket erstellen
DatagramPacket sendStartPaket = new DatagramPacket(StartByte,StartByte.length,IP,port );
DatagramPacket receiveStartPaket = new DatagramPacket(receiveStartData, receiveStartData.length);

byte[] conbyte;
conbyte = sendStartPaket.getData();

// noch rauswerfen, wen es läuft
int namelen = conbyte.length-8-4;
byte[] name = new byte[namelen]; // byte für Dateinamen anlegen

name = TransferBytes(conbyte, 0, namelen-1); // Dateiname

System.out.println("Name: "+new String(name));
[/PHP]

Wichtiger ist aber der Server:

[PHP]
int port = Integer.parseInt(args[0]);


try{
/* UDP-Socket erstellen */
DatagramSocket serversock = new DatagramSocket(port);
//DatagramPacket request = new DatagramPacket(new byte[1024], 1024);
DatagramPacket request = new DatagramPacket(new byte[270], 270);
while(true){

try{
System.out.println("Warte auf Verbindung von Client...");
serversock.receive(request);
System.out.println("Verbindung aufgebaut, Paketgröße:"+request.getLength() );
//***********************
byte[] b;
b = request.getData();

System.out.println("Bytegröße: "+b.length);

int namelen = b.length-8-4;
byte[] name = new byte[namelen]; // byte für Dateinamen anlegen

name = TransferBytes(b, 0, namelen-1); // Dateiname

System.out.println("Name vor dem Thread: "+new String(name));

Das DatagramPacket, was ich bekomme ist identisch, mit dem, was ich beim Client habe. Trotzdem bekomme ich als Name, beim Verwenden des selben Codes für das Auslesen des Namen diese Ausgabe: "Testdatei�N". Und das verstehe ich nicht.

Ich habe zumindest schon festgestellt, dass mein Paket, welches genau 21 Byte groß ist ( auch das DatagramPacket, was der Server erhält ) beim Aufruf von getData() auf einmal beim Server 258 Byte groß ist.


java UDP_Server 3000

Warte auf Verbindung von Client...

Verbindung aufgebaut, Paketgröße:21

Bytegröße: 270

size: 258

Name vor dem Thread: Testdatei�N

Ich weiß nicht so richtig wo der Fehler liegt. Kann mich unter Umständen bitte jemand aufklären?^^

Gruß

int namelen = b.length-8-4;

und

name = TransferBytes(b, 0, namelen-1); // Dateiname

Kann es sein, dass hier vielleicht ein Newline-Zeichen in das Array einfliesst?

Gib doch mal den String im Hex-Format aus, dann siehst Du welche(s) Zeichen am Schluss ausgegeben wird.

  • Autor

Morgen uenetz, ich hab den Teil beim Server mal so angepasst:


System.out.println("Länge des Namen(9): "+namelen);

name = TransferBytes(b, 0, namelen-250); // liefert genau "Testdatei"

System.out.println("Name vor dem Thread: "+new String(name));

name = TransferBytes(b, 0, namelen-1); // liefert genau "Testdatei"

System.out.println("Name in Hex vor dem Thread: "+toHex(new String(name)));
[/PHP]

Das hier ist die Ausgabe:

[code] Warte auf Verbindung von Client... Verbindung aufgebaut, Paketgröße:21 Bytegröße: 270 Länge des Namen(9): 258 size: 9 Name vor dem Thread: Testdatei size: 258 Name in Hex vor dem Thread: 54657374646174656900000000000000000000efbfbd4e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 [/code]

Hmm, das überrascht mich jetzt weniger. Dass es funktioniert, wenn ich 250 Byte abziehe ist klar. Immerhin ist ja auch mein Problem, dass der aus dem Paket, welches beim Erhalten noch 21 Byte groß ist, nach getData ein Byte-Array macht, welches 270 Byte groß ist oO. Die Nullen zwischen dem String und den Zahlen, die hier scheinbar mit ausgegeben werden, sollten aber stimmen, da die Dateigröße ( 0 ) als long gespeichert wurde. Doch warum ist mien Byte plötzlich so gigantisch groß? :(

Gruß

eigentlich dachte ich an die zeichenweise Ausgabe des Dateinamen im Hex-Format, damit man sehen kann, welche Zeichen der String beinhaltet.

Es kann z.B. ein "\n" am Ende stehen, was zu der Ausgabe des Sonderzeichens führen kann ;)

  • Autor
eigentlich dachte ich an die zeichenweise Ausgabe des Dateinamen im Hex-Format, damit man sehen kann, welche Zeichen der String beinhaltet.

Es kann z.B. ein "\n" am Ende stehen, was zu der Ausgabe des Sonderzeichens führen kann ;)

Kann das überhaupt sein, wenn mein Client nur so viele Bytes in das StartByte schiebt, wie die Zeichenkette "Testdatei" benötigt?

Was ist TransferBytes? Ist die von dir? Ist sichergestellt, dass da drin nicht irgendein Murks passiert?

Was liefert request.getOffset()?

Hallo Klotzkopp!

Ja, das ist von mir:


public static byte[] TransferBytes(byte[] bytes, int start, int end){
int size = end-start+1;
System.out.println("size: "+size);
byte[] newByte = new byte[size];
for(int x=start, y = 0;x<=end;x++,y++){
newByte[y]=bytes[x];
}

return newByte;
}
[/PHP]

Ich hatte auch am Anfang überlegt ob ich da keinen Mist zusammengebraut habe. Deshalb habe ich ja beim Client kurz vor dem Abschicken nochmal das DatagramPacket so auseinander genommen, wie es dann der Server macht undzwar mit den selben Funktionen. Dort funktioniert es. Der Fehler tritt ja schon vor dem ersten Aufruf von TransferByte auf. getData() gibt mir aus meinem 21 Byte großen DatagramPacket ein Byte zurück, welches viel größer ist. Das versteh ich halt nicht. Beim Client habe ich das ja nochmal getestet, angefangen mit getData(). Ausgehend von der Größe meines neuen, aber zu großen Bytes liefert TransferByte schon das, was es soll.

Das hier wolltest du noch:

[code] Warte auf Verbindung von Client... Verbindung aufgebaut, Paketgröße:21 request.getOffset(): 0 Bytegröße: 270 [/code]

Ich sehe grade:

[PHP]
DatagramPacket request = new DatagramPacket(new byte[270], 270);

Daher kommen also die 270 Byte. Aber das Paket gibt doch zunächst 21 Byte als Größe an. Dass ich das weiß, hilft mir grade nicht wirklich weiter^^

Archiv

Dieses Thema wurde archiviert und kann nicht mehr beantwortet werden.

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.