2017-09-12 4 views
-2

Hallo und vielen Dank im Voraus,Java UDP - Senden eine String-Array vom Server zum Client

Also ich versuche, eine Reihe von JList Gegenständen zu nehmen und sie in einen String Array konvertieren (was ich denke, ich habe richtig), und dann versuche ich, dieses String-Array an meinen Client zu senden, der dann versuchen wird, sie in einer JList auf ihrer Seite anzuzeigen.

Ich habe ein paar verschiedene Dinge ausprobiert, aber keine funktionieren.

Hier ist mein letzter Code Versuch über das String-Array zu senden:

String[] FilesList = (String[]) lClient1Files.getSelectedValues(); 

FilesBuffer = FilesList.getBytes(); 

DatagramPacket DGPFilesResponse = new DatagramPacket(FilesBuffer,FilesBuffer.length, DGP.getAddress(), DGP.getPort()); 
SeederSocket.send(DGPFilesResponse); 

Die Linie: FilesBuffer = FilesList.getBytes(); das Problem verursacht, weil getBytes() hier nicht anwendbar ist.

Also meine Fragen sind: 1) Wie kann ich das Array von JList Artikel senden (sie sind Namen) über an den Client (es insbesondere nicht zu einem String-Array) sein müssen, und 2) Wie würde Ich erhalte die Liste auf der Kundenseite, damit ich sie verwenden kann?

Vielen Dank.

+0

Java-Variablen sollten mit einem Kleinbuchstaben beginnen. 'String [] filesList',' filesBuffer = filesList.getBytes() '. Klingt kleinlich, aber Java-Programmierer werden Ihre Fragen leichter beantworten, wenn sie Ihren Code einfach lesen können. – slim

+0

Ich verstehe. Vielen Dank. – Impact

+0

Und dennoch haben Sie Ihren Code nicht bearbeitet, um die Vorschläge von slim zu berücksichtigen. –

Antwort

2

Man muss ein Binärformat für das String-Array erstellen.

ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
try (DataOutputStream dos = new DataOutputStream(baos)) { 
    dos.writeInt(filesList.length); 
    for (String files : filesList) { 
     dos.writeUTF(files); 
    } 
} 
byte[] bytes = baos.toByteArray(); 

Diese intern für einen String schreibt zuerst die Länge in Bytes und verwendet String.getBytes("UTF-8") so kann eine beliebige Zeichenfolge geschrieben werden.

Das Lesen gehört zu den umgekehrten Eingangsklassen.

Wenn du da draußen viele Kunden zu haben glauben, vielleicht mit verschiedenen Versionen, fügen dann in der Nachricht eine Version Nummer.


Auf der anderen Seite

ByteArrayInputStream bais = new ByteArrayInputStream(bytes); 
try (DataInputStream dis = new DataInputStream(baos)) { 
    int stringsCount = dis.readInt(); 
    String[] filesList = new String[stringsCount]; 
    for (int i = 0; i < stringsCount; ++i) { 
     filesList[i] = dis.readUTF(); 
    } 
    return filesList; 
} 
+0

@slim ja, ich war ein bisschen faul: der Code ist nicht völlig symmetrisch. –

+0

Danke. Es hat den Code ausprobiert (und die Symmetrie behoben), und ich bekomme einen Fehler: 'Ausnahme im Thread "AWT-EventQueue-0" java.lang.ClassCastException: [Ljava.lang.Object; kann nicht in [Ljava.lang.String; ' . Der Fehler sagt auch: bei 'ClientFrame1 $ 2.actionPerformed (ClientFrame1.java:161)', die auf diese Zeile verweist: 'String [] FilesList = (String []) lClient1Files.getSelectedValues ​​();'. Ich glaube, das Array hat Probleme, von JList in String-Array konvertiert zu werden, aber ich bin mir nicht sicher. Gibt es möglicherweise einen anderen Weg, wie ich die Konvertierung machen könnte? – Impact

+0

Schauen Sie sich https://docs.oracle.com/javase/8/docs/api/javax/swing/JList.html - (1) 'JList ' an und besonders (2) sollte man 'getSelectedValueList()' verwenden gibt anstelle eines Arrays eine 'List ' zurück. –

0

Die UDP-Nutzlast hat ein byte[] sein. Sie müssen einen Weg wählen, Ihre Daten in eine byte[] zu codieren, so dass sie auf der Empfängerseite zurückkonvertiert werden kann.

So müssen Sie encode() und decode() so dass Unit-Tests wie diese Arbeit schreiben:

@Test 
public void encodesAndDecodesStringArray() { 
    String[] strings = new String[] { "foo", "bar" }; 
    byte[] encoded = Encoder.encode(strings); 
    String[] decoded = Encoder.decode(encoded); 

    assertThat(decoded, is(strings)); 
} 

Es gibt buchstäblich Hunderte von Kodierungsschemata Sie wählen könnten. Trennzeichen-getrennt, längengetrennt, JSON, XML, BSON, ASN.1 ... werfen Sie einen Blick auf Wikipedia's List of data serialization formats.

Eine sehr einfache Möglichkeit, die für Sie arbeiten ist Begrenzer-Trennung:

public byte[] encode(String[] strings) { 
    return String.join(",", strings).getBytes(UTF_8); 
} 

public String[] decode(byte[] encodedArray) { 
    return new String(encodedArray, UTF_8).split(","); 
} 

Aber beachten Sie, dass diese sehr grundlegende Schema versagt, wenn eine der Eingabezeichenfolgen enthält ein „“ (oder was auch immer Begrenzer Sie wählen). Wählen Sie ein Schema, das für Sie arbeitet.

Verwenden Sie JSON - es gibt einfach zu verwendende Bibliotheken zum Lesen und Schreiben von JSON.Lesbares ASCII in Netzwerk-Traces ist oft praktisch. Der Platzbedarf ist nicht so hoch. Es ist bereit für beliebig komplexe hierarchische Datenstrukturen.

Berücksichtigen Sie, dass der Empfänger auch geändert werden muss, wenn Sie die Struktur der von Ihrem Absender erstellten Daten ändern. Wenn das wichtig ist, sollten Sie eine Protokollversion in das übertragen, was Sie senden (es reicht vielleicht, nur zu sagen "die ersten beiden Bytes sind die Version", und stecken Sie immer einen 0x0001 da hinein, um damit zu beginnen).

Verwandte Themen