CRC geprüfte UDP Pakete..

Kalkulon

Mitglied
Hallo, habe ein Problem. Wenn ich den CRC Wert des Inhaltes eines UDP Paketes berechne danach das Paket verschicke und nochmals den CRC Wert des Inhalts berechne kommt ein anderer Wert raus! Was mache ich falsch?

Java:
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.zip.CRC32;


public class Test {

	/**
	 * @param args
	 */
	public static void main(String[] args) throws IOException {
		DatagramSocket socket = new DatagramSocket(5008);
		
		byte[] data = "zu verschickende Daten....".getBytes();
		
		CRC32 crc = new CRC32();
		crc.update(data);
		System.out.println(crc.getValue());
		DatagramPacket packet = new DatagramPacket(data, data.length);
		packet.setPort(5008);
		packet.setAddress(InetAddress.getByName("localhost"));
		socket.send(packet);
		byte[] buf = new byte[508];
		DatagramPacket packetIn = new DatagramPacket(buf, 508);
		socket.receive(packetIn);
		
		byte[] test = packetIn.getData();
		
		crc.reset();
		crc.update(test);
		
		System.out.println(crc.getValue());
	}
	

}

Etwas habe ich schon rausgefunden, wenn ich genau weiß wie groß der Inhalt des Paketes ist und ich nur genau die Größe angebe beim Empfangen des Paketes klappt es mit der Berechnung des CRC's. Was mache ich aber, wenn ich nicht genau weiß wie groß das Paket ist?
 
Zuletzt bearbeitet:
S

SlaterB

Gast
ich meine in deinem Testprogramm, schau dir deine beiden Arrays an, dann könnte dir der Fehler sofort auffallen,
wenn du CRC auf unterschiedlichen Arrays ausführst kannst du das dem nicht anlasten
 
S

SlaterB

Gast
was heißt leider nicht?
na gut, ich verrate es dir, schon die grundlegendste Eigenschaft ist anders: die Arrays sind nicht gleich lang

wieso sind eigentlich beim Empfänger genau 508 Bytes vorgesehen, das sieht ja sehr speziell aus,
dann kannst du auch gleich den passenden 508er String beim Empfänger in der Quellcode schreiben
 

Kalkulon

Mitglied
wenn ich aber weiß wie groß der Content ist klappt es ja mit dem CRC!

Java:
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.zip.CRC32;


public class Test {

	/**
	 * @param args
	 */
	public static void main(String[] args) throws IOException {
		DatagramSocket socket = new DatagramSocket(5008);
		
		byte[] data = "zu verschickende Daten....".getBytes();
		
		CRC32 crc = new CRC32();
		crc.update(data);
		System.out.println(crc.getValue());
		DatagramPacket packet = new DatagramPacket(data, data.length);
		packet.setPort(5008);
		packet.setAddress(InetAddress.getByName("localhost"));
		socket.send(packet);
		byte[] buf = new byte[508];
		DatagramPacket packetIn = new DatagramPacket(buf, 508);
		socket.receive(packetIn);
		packetIn.getData();
		crc.reset();
		crc.update(buf,0,26);
		System.out.println(crc.getValue());
	}
}
 
S

SlaterB

Gast
genau, du musst erst wissen, wie groß der Content ist, sonst klappt CRC nicht,
das ist kein Problem sondern eine wichtige Grundlage

56
hat eine andere Prüfsumme als
560
oder
5600
oder
56000000000000000000000000

du kannst nicht beliebig 0en ranhängen und erwarten dass sie ignoriert werden,
bei einfachen Verfahren wie Quersumme in der Mathematik mag das der Fall sein, hier aber anscheinend nicht,
und allgemein ist das doch eine wichtige Information, stell dir vor das wär ein Geldbetrag ;)

unabhängig von CRC musst du erstmal über UDP das Original-byte-Array wiederherstellen, vorher geht gar nix
 
T

tuxedo

Gast
Ich denke es ist noch ein wenig komplexer:

UDP Pakete können unterwegs fragmentiert werden. D.h. es ist nicht gesagt dass wenn du 508 bytes in einem Paket abschickst, du auf empfängerseite auch die 508 bytes am Stück bekommst. Eventuell kommen mit dem ersten lesen nur 400 bytes an. Dann hast du zwar schonmal die größe, musst aber schauen dass du die noch fehlenden 108 bytes kriegst.

Theoretisch wird's sogar noch komplexer:
Wenn zwei 508 bytes Pakete fragmentiert werden:

Paket A_0 = 400 bytes
Paket A_1 = 108 bytes
Paket B_0 = 300 bytes
Paket B_1 = 208 bytes

Da die Reihenfolge der empfangenen Pakete beliebig sein kann, könnte die Empfangsreihenfolge so aussehen:

A_0
B_1
B_0
A_1

Viel Spass beim zusammensetzen ;-) Wobei ich mir bei dieser Aussage nicht 100%ig sicher bin ob das technsich vollständig korrekt ist.. Aber immerhion bin ich mir 90%ig sicher.
Solltest da jedenfalls nochmal ein wenig recherchieren bevor du alles festzurrst.

- Alex
 

Empire Phoenix

Top Contributor
Wozu der blödsinn ?
Udp hat inner implementation bereits einen CRC algoritmus drinne, fehlerhafte packet werden schlichtweg gedroppt. Kannst dir also eine eigene Feherüberprüfung sparen, wenns ankommt ist die checksum korrekt
Fragmentierung bin ich nciht hunderprozentig sicher, aber bisslang war übers internet 2-3k packete kein problem mit fragmentierung, ein kurzer check bei google hat mitr aber gerade gesagt das das reassembling im ip protokoll bereits gemacht wird, daher sollte das auch egal sein.
 
Zuletzt bearbeitet:
T

tuxedo

Gast
Hmm, wie ist das denn mit Fragmenten? Wenn da eins von 2 Fragmenten eines einzelnen Pakets verloren geht: Wird dann das zweite Fragment mit gedroppt?

- Alex
 

Empire Phoenix

Top Contributor
Jep, bereits auf unteren ebenen so wie es aussieht weil das reassemblen dann scheitert.

--------------------------

Btw für dich als TCP liebhaber bei spielen mal dazugepackt.
Nutzlast 400byte,
-> Overhead duch Ethernet layer + IpLayer + Tcp layer = 5xx byte
-> weniger als 50% effizienz
Udp
400byte nutzlast
-> overhad durch ip (160) + Etherent (160) + Udp(20) + short zur flusskontrolle(2byte) = 342 byte
-> rund 200 byte gesparrt
Bei kleineren Packeten wird das sogar noch schlimmer, und updates von positionen sind nicht gerade groß.
 
Zuletzt bearbeitet:
T

tuxedo

Gast
Jep, bereits auf unteren ebenen so wie es aussieht weil das reassemblen dann scheitert.

Ah, wusste nicht dass UDP die Fragmente selbst wieder zusammensetzt. Danke für die Info.


Btw für dich als TCP liebhaber bei spielen mal dazugepackt.

Ich bin kein "TCP Liebhaber bei Spielen". Ich sag nur man sollte wissen wo die einzelnen Stärken und Schwächen liegen.


Nutzlast 400byte,
-> Overhead duch Ethernet layer + IpLayer + Tcp layer = 5xx byte
-> weniger als 50% effizienz
Udp
400byte nutzlast
-> overhad durch ip (160) + Etherent (160) + Udp(20) + short zur flusskontrolle(2byte) = 342 byte
-> rund 200 byte gesparrt
Bei kleineren Packeten wird das sogar noch schlimmer, und updates von positionen sind nicht gerade groß.

Deine Rechnung kann ich so nicht ganz unterschreiben.

Hier wird TCP mit UDP vergleichen

http://sd.wareonearth.com/~phil/net/overhead/ hat gesagt.:
TCP over Ethernet:
Assuming no header compression (e.g. not PPP)
Add 20 IPv4 header or 40 IPv6 header (no options)
Add 20 TCP header
Add 12 bytes optional TCP timestamps
Max TCP Payload data rates over ethernet are thus:
(1500-40)/(38+1500) = 94.9285 % IPv4, minimal headers

(1500-52)/(38+1500) = 94.1482 % IPv4, TCP timestamps
(1500-52)/(42+1500) = 93.9040 % 802.1q, IPv4, TCP timestamps
(1500-60)/(38+1500) = 93.6281 % IPv6, minimal headers
(1500-72)/(38+1500) = 92.8479 % IPv6, TCP timestamps
(1500-72)/(42+1500) = 92.6070 % 802.1q, IPv6, ICP timestamps

UDP over Ethernet:
Add 20 IPv4 header or 40 IPv6 header (no options)
Add 8 UDP header
Max UDP Payload data rates over ethernet are thus:
(1500-28)/(38+1500) = 95.7087 % IPv4

(1500-28)/(42+1500) = 95.4604 % 802.1q, IPv4
(1500-48)/(38+1500) = 94.4083 % IPv6
(1500-48)/(42+1500) = 94.1634 % 802.1q, IPv6


geht man bei beiden von IPv4 aus und nimmt man beiden den Best-Case, dann steht TCP mit 94.9285 % gegenüber 95.7087 % von UDP. Die Differenz beträgt 0,7% ... Ich denke das veranschaulicht meine bisherigen Statements recht gut ...
 

Ähnliche Java Themen


Oben