String[] wird zu null bei Serialisierung

lumo

Top Contributor
Hallo,

ich schreibe gerade eine client/server anwendung und muss zugeben dass ich etwas dumm in die röhre kucke.

ich schicke meine objekte hin und her, ohne probleme.
wenn ich aber ein String[] als parameter eines objektes mitsende, wird daraus null
muss ich das array wirklich in einen string mit trennzeichen umwandeln? - oder in eine liste...

hoffe dass ich sonst irgendwas falsch mache... denn arrays wären mir am liebsten...

hier mal kurz der CLIENT log
(20:33:43.174) Client: sending Command. enum Chat = {name=Chat, cmd='/chat', args.length='1', args='[test]'}
(20:33:43.174) Client.onData(): DataPacket [type=10, data='ChatMessage [timestamp=20:33:43.174, from=BulletCollector, to=All, msg=null]', msg='Sending ChatMessage']
also der client sendet den enum chat raus, der client returniert ein datenpaket, wo die args von enum als msg drin sein sollte. tun sie aber nicht. nun denkt ihr sicher: der macht was beim umwandeln falsch... dachte ich auch!
doch dann hab ich den SERVER log gesehen
(20:33:43.174) Server.onData(): DataPacket [type=99, data='enum Chat = {name=Chat, cmd='/chat', args.length='1', args='[null]'}', msg='Sending Command enum Chat = {name=Chat, cmd='/chat', args.length='1', args='[test]'}']
(20:33:43.174) Server Broadcast: DataPacket [type=10, data='ChatMessage [timestamp=20:33:43.174, from=BulletCollector, to=All, msg=null]', msg='Sending ChatMessage']
und da sagt er mir, dass er bereits im enum chat als args ein [null] stehen hat (und dann steht dort, nach sending command, dass er aber einen enum MIT args =[test] weggeschickt hat!)

ergo, da ging was schief...

kann mir jemand erklären was da falsch läuft - SOLL das so sein?
 
Zuletzt bearbeitet von einem Moderator:
S

SlaterB

Gast
zur Implementierung der Versendung schreibst du wenig, ObjectStreams?
was genau sind die Logs, Beschreibungen der Objekte jeweils VOR dem Versenden, NACH dem Entpacken?

falls du normale Objekte mehrfach über denselben ObjectStreams versendest, werden sie standardmäßig gecacht, da hilft reset()

bei richtigen Java-Enum-Klassen kannst man durchaus damit rechnen, das sparsamerweise nur die Nummer versendet und auf anderer Seite einfach der x-te Enum-Wert mit dem dortigen Zustand genommen wird,
Enums eignen sich nun wahrlich nicht zum dynamischen Informationstransport,
alles intensiv auszuprobieren
 
Zuletzt bearbeitet von einem Moderator:

lumo

Top Contributor
hier mal die funktionen zum senden und empfangen:
Java:
public static boolean send(INonBlockingConnection nbc, DataPacket packet) {
		try {
			if (packet == null) {
				return false;
			}
			ByteArrayOutputStream bout = new ByteArrayOutputStream();
			ObjectOutputStream oos = new ObjectOutputStream(bout);
			oos.writeObject(packet);
			nbc.write(bout.toByteArray());
			nbc.write(DELIMITER);
			oos.close();
			bout.close();
		} catch (BufferOverflowException e) {
			return false;
		} catch (IOException e) {
			System.err
					.println("you try to send an Object (packet.getData()), which is not Serializable: "
							+ packet);
		}
		return true;
	}

	public static DataPacket receive(INonBlockingConnection nbc)
			throws IOException {
		if (!nbc.isOpen()) {
			System.out.println("cannot receive, nbc is closed.");
		}
		if (nbc.isReceivingSuspended()) {
			System.out.println("cannot receive, receiving is suspended!");
		}
		if (nbc.available() <= 0) {
			System.out.println("cannot receive, nothing available to read");
		}
		byte[] bytes = null;
		DataPacket packet = null;
		do {
			try {
				bytes = nbc.readBytesByDelimiter(DELIMITER);
				ByteArrayInputStream bin = new ByteArrayInputStream(bytes);
				ObjectInputStream in = new ObjectInputStream(bin);
				packet = (DataPacket) in.readObject();
				in.close();
				bin.close();
			} catch (BufferUnderflowException bue) {
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			}
		} while (bytes == null);
		return packet;
	}

ich schicke z.Z. enums, die werden dann mit integer werten ersetzt um daten zu sparen, jetzt will ich erstmal dass es übersichtlich ist und alles funktioniert :)
 
S

SlaterB

Gast
dieser Code schließt Cache-Probleme aus,
dass du beim Senden das byte[] vor dem close() holst könnte ein Problem sein, aber wird deswegen einfach ein Wert null?
eher sollte ja alles kaputt gehen..

ansonsten sehe ich nichts, mit INonBlockingConnection und deiner Schleife beim Lesen sind aber noch manch mir etwas unbekannte Bestandteile dabei,
vorallem wäre jetzt aber spannend wie DataPacket aufgebaut ist, was genau zum Senden übergeben wird usw., der Komplettablauf

anbei ein vollständiges Testprogramm von mir, welches selbstverständlich funktioniert, arbeitet nur mit bis zum byte[],
auf dieser Ebene kannst du ja testen ob das zumindest bei dir auch geht:
Java:
public class Test {
	public static void main(String[] args) throws Exception {
		DataPacket d = new DataPacket();
		d.data = new String[] { "test" };
		byte[] b = send(d);
		d.data = new String[] { "test2" };

		DataPacket d2 = receive(b);
		System.out.println(Arrays.toString((String[]) d2.data));
		System.out.println(Arrays.toString((String[]) d.data));
	}

	public static byte[] send(DataPacket packet) throws Exception {
		ByteArrayOutputStream bout = new ByteArrayOutputStream();
		ObjectOutputStream oos = new ObjectOutputStream(bout);
		oos.writeObject(packet);
		oos.close();
		bout.close();
		return bout.toByteArray();
	}

	public static DataPacket receive(byte[] bytes) throws Exception {

		ByteArrayInputStream bin = new ByteArrayInputStream(bytes);
		ObjectInputStream in = new ObjectInputStream(bin);
		DataPacket packet = (DataPacket) in.readObject();
		in.close();
		bin.close();
		return packet;
	}
}

class DataPacket implements Serializable {
	Object data;
}
Ausgabe:
Code:
[test]
[test2]
 

lumo

Top Contributor
hier noch die daten-klassen Command & DataPacket

ich habe allerdings schon eine klasse zum testen dazu geschrieben und...
es kommt das richtige raus.

achja, der INonBlockingConnection über den ich sende ist der von xSocket!

Java:
package tests;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

import lumo.net.clientserver.protocol.Command;
import lumo.net.clientserver.ssl.DataPacket;

public class Test {
    public static void main(String[] args) throws Exception {
        DataPacket d = new DataPacket();
        d.setData(Command.fromString("test"));
        byte[] b = send(d);
        d.setData(Command.fromString("/pm slater test"));
 
        DataPacket d2 = receive(b);
        System.out.println(d);
        System.out.println(d2);
    }
 
    public static byte[] send(DataPacket packet) throws Exception {
        ByteArrayOutputStream bout = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bout);
        oos.writeObject(packet);
        oos.close();
        bout.close();
        return bout.toByteArray();
    }
 
    public static DataPacket receive(byte[] bytes) throws Exception {
 
        ByteArrayInputStream bin = new ByteArrayInputStream(bytes);
        ObjectInputStream in = new ObjectInputStream(bin);
        DataPacket packet = (DataPacket) in.readObject();
        in.close();
        bin.close();
        return packet;
    }
}


Java:
package lumo.net.clientserver.ssl;

import java.io.Serializable;

public class DataPacket implements Serializable {
	private static final long serialVersionUID = -5899002285730447746L;

	private int header;
	private Object data = null;
	private String msg = "";

	public DataPacket setHeader(int header) {
		this.header = header;
		return this;
	}

	public int getHeader() {
		return header;
	}

	public void setData(Object data) {
		this.data = data;
	}

	public Object getData() {
		return data;
	}

	public String getMsg() {
		return msg;
	}

	public void setMsg(String msg) {
		this.msg = msg;
	}

	@Override
	public String toString() {
		return String.format("DataPacket [type=%s, data='%s', msg='%s']",
				header, data, msg);
	}
}

Java:
package lumo.net.clientserver.protocol;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public enum Command implements Serializable, Comparable<Command> {
	ChangeNick("/nick", 1), ChangeOtherNick("/nick", 2), ChangeRights(
			"/rights", 2), PrivateMessage("/pm", 2), Chat("/chat", 1), Kick(
			"/kick", 1), KickBecause("/kick", 2);

	private transient String cmdString;
	private String[] args;

	Command(String cmd, int argCount) {
		this.cmdString = cmd;
		args = new String[argCount];
	}

	public String getCmd() {
		return cmdString;
	}

	public int getArgCount() {
		return args.length;
	}

	public String[] getArgs() {
		return args;
	}

	public String getArg(int i) {
		try {
			return args[i];
		} catch (Exception e) {
			return "Index Out of Range!";
		}
	}

	public static Command getStartCommand(String str) {
		str = str.trim();
		Command[] cmds = Command.values();
		int argCount = str.split(" ").length;
		List<Command> possibleHits = new ArrayList<Command>();
		for (int i = 0; i < cmds.length; i++) {
			if (str.toLowerCase().startsWith(cmds[i].getCmd())) {
				possibleHits.add(cmds[i]);
			}
		}

		// only one possible hit!
		if (possibleHits.isEmpty()) {
			return Command.Chat;
		}
		if (possibleHits.size() == 1) {
			return possibleHits.get(0);
		}
		// we got more choices!
		Collections.sort(possibleHits, new CommandSorter());
		for (int i = 0; i < possibleHits.size(); i++) {
			Command c = possibleHits.get(i);
			if ((argCount - 1) == c.getArgCount()) {
				return c;
			}
		}
		return possibleHits.get(possibleHits.size() - 1);
	}

	public static Command fromString(String input) {
		Command cmd = Command.getStartCommand(input);
		if (cmd.equals(Command.Chat)) {
			cmd.args[0] = input;
		} else {
			// its a command
			input = input.substring(cmd.getCmd().length() + 1);
			String[] args = input.split(" ");
			if (args.length == cmd.getArgCount()) {
				// arg count does match
				cmd.args = args;
			} else if (args.length > cmd.getArgCount()) {
				int beginIndex = 0;
				for (int i = 0; i < cmd.getArgCount() - 1; i++) {
					cmd.args[i] = args[i];
					beginIndex += args[i].length() + 1; // +1 due space
				}
				cmd.args[cmd.getArgCount() - 1] = input.substring(beginIndex);
			}
		}
		return cmd;
	}

	public String toString() {
		return String.format(
				"enum Chat = {name=%s, cmd='%s', args.length='%d', args='%s'}",
				name(), getCmd(), args.length, Arrays.toString(args));
	}

	public static void check(List<String> strings) {
		for (int i = 0; i < strings.size(); i++) {
			String cmd = strings.get(i);
			System.out.println("\n" + Command.fromString(cmd));
		}
	}

	public static void main(String[] args) {
		List<String> strings = new ArrayList<String>();
		strings.add("/nick bulletcollector");
		strings.add("/nick lumo bulletcollector");
		strings.add("/rights lumo EDIT");
		strings.add("/pm lumo hallo alter sack");
		strings.add("/kick bulletcollector");
		strings.add("/kick bulletcollector lamer! laber mich nicht voll!");
		strings.add("Hello World!");
		check(strings);
	}
}
 

lumo

Top Contributor
so hab jetzt noch was versucht...
und zwar hab ich deine funktion zum senden aus der test app in meine app geschrieben

und zwar bekommt der client immer seine msg zurück.
wenn ich zwei clients habe und je eine msg schicke
bekommt A die msg die A geschickt hat.
und B die msg die B geschickt hat.

egal ob a oder b senden...

also A sendet TEST
A empfängt angeblich TEST
B empfängt NULL

B sendet HALLO
A empfängt TEST
B empfängt HALLO

das kann doch eigentlich gar nicht sein...

EDIT: wenn du dich bereiterklärst den code anzusehen würde ich dir das ganze paketchen mal schicken... als zip (per email)
 
Zuletzt bearbeitet:
S

SlaterB

Gast
wie schon in erster Antwort recht deutlich geschrieben bietet sich Enum absolut nicht zur Übertragung an,

ändere das temporär in eine normale Klasse, lasse Command.getStartCommand(input) neue Objekte erzeugen,
passe weiterhin an was anzupassen ist (equals), teste dann ob die Übertragung klappt

Enums sind feste vorgegebene Werte, dass aus der Deserialisierung neue zusätzliche Enum-Werte herauskommen wirst du sicher auch nicht annehmen, widerspräche ja komplett dem Konzept,
allerhöchstens könnte nach Deserialisierung im vorhandenen Enum-Wert die Daten geändert werden,
einfach so während andere Klassen vielleicht parallel damit arbeiten? reichlich merkwürdig, selbst wenn es funktioniert,
ich weiß es nicht, will ich auch gar nicht testen, das ist kein sinnvolles Konzept,

was ist wenn ein Server relativ gleichzeitig von zwei Clients dieselben Commands erhält, wird dann zweimal schnell überschrieben?,
sieht es dann für den Server in der weiteren Verarbeitung aus als hätten beide dieselbe Nachricht geschickt, einem Client wird die Nachricht des anderen untergemogelt?
abenteuerlich

nein, Enum bleibt unveränderlich, du kannst ja gerne die Menge der Commands begrenzen und unterscheiden,
aber args sind dann zusätzliche Nutzdaten im DataPacket


-----

übrigens sind alle Enums vom Haus aus Serializable, vielleicht weil eben nur die Nummer/ der Name übertragen
 
Zuletzt bearbeitet von einem Moderator:

lumo

Top Contributor
also es lag wirklich am enum
danke dass du mir das erklärt hast, ich wusste nicht, dass der enum was statisches sein muss/ist.

für mich waren nur die funktionen wie verwendung im switch von interesse... das geht jetzt mit der id = Header int...

DANKE!
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
F Stream wird als Char übertragen. Char -> in String umwand Netzwerkprogrammierung 5
T String von Client zu Server kommt nicht an Netzwerkprogrammierung 92
T Brauche Hilfe beim GET-String für HttpURLConnection Netzwerkprogrammierung 4
T server empfängt nur 1 Buchstaben vom String Netzwerkprogrammierung 1
N Name eines Attributes aus einem festen String und einer Variablen generieren Netzwerkprogrammierung 5
S Socket String InputStream in hex umwandeln Netzwerkprogrammierung 1
T Socket Gleiche String ungleich? Netzwerkprogrammierung 8
M Socket String Arrays über Socket an Server schicken Netzwerkprogrammierung 2
F String in Datenbank speichern Netzwerkprogrammierung 1
I RMI String Netzwerkprogrammierung 2
precoc String Array versenden Netzwerkprogrammierung 7
T Socket String zu Socket Netzwerkprogrammierung 26
7 String an Server Netzwerkprogrammierung 2
S WebService, 4-stelliger String (Jahr) als Calendar Netzwerkprogrammierung 5
M String an PHP Script aus Java übergeben Netzwerkprogrammierung 12
N String als byte Array über Socket versenden Netzwerkprogrammierung 8
M Messenger - String oder Objekte Netzwerkprogrammierung 4
T Socket Nullterminierten String lesen Netzwerkprogrammierung 4
J Datei übertragen ja String + datei übertragen nein Netzwerkprogrammierung 5
H String Array durch einen Stream schicken. Netzwerkprogrammierung 4
N Socket Stream in String Netzwerkprogrammierung 4
J Browser-String angeben Netzwerkprogrammierung 5
S String[] über Socket senden Netzwerkprogrammierung 3
G String in InetAddres umwandeln klappt nicht Netzwerkprogrammierung 5
A String per ByteBuffer empfangen? Netzwerkprogrammierung 6
ModellbahnerTT Problem feste String ins Netzwerk zu geben Netzwerkprogrammierung 5
G UTF-8 in STring umwandeln oder umgedreht Netzwerkprogrammierung 12
F String in eine URL umwandeln Netzwerkprogrammierung 7
P string over net Netzwerkprogrammierung 4
T Html-Source über URL in einen String speichern? Netzwerkprogrammierung 16
B HEX String zu einem Byte Array ? *verzweiflung* :( Netzwerkprogrammierung 16
K String zurück liefern ! Netzwerkprogrammierung 4
S SSLSocketFactory.createSocket(String hostname, int port),wo? Netzwerkprogrammierung 5
O Ip-String in byte[]-Array umwandeln? Netzwerkprogrammierung 3
C gesendeten String einlesen Netzwerkprogrammierung 3
G String to Socket ? Netzwerkprogrammierung 3
A StringCorruptedException: invalid String header Netzwerkprogrammierung 2
A Bei FTP Übertragung wird Datei nicht komplett übertragen Netzwerkprogrammierung 2
OnDemand JMS Messages wird gecached Netzwerkprogrammierung 2
P RMI stub wird nicht gefunden Netzwerkprogrammierung 8
I Socket ObjectOutputStream-Socket: Objekt wird falsch übertragen Netzwerkprogrammierung 2
M com.google.gson wird nicht erkannt Netzwerkprogrammierung 2
F Website parsen, die mit javascript zusammengebaut wird Netzwerkprogrammierung 1
P Socket Server übertragung wird immer langsamer Netzwerkprogrammierung 4
A Socket Socket-Problem - Object wird nicht übertragen Netzwerkprogrammierung 3
M Client sendet nur, wenn das Socket geschlossen wird Netzwerkprogrammierung 53
L Server anpingen (Pingzeit) ?? Pingzeit wird nicht verändert Netzwerkprogrammierung 6
M JSP wird im gesamten Projekt nicht neugeladen Netzwerkprogrammierung 3
K Socket InputStream wird nicht erzeugt Netzwerkprogrammierung 4
R Socket SSL-Connect in Servlet - keystore wird nicht gefunden Netzwerkprogrammierung 2
S anderer Rechner wird nicht gefunden Netzwerkprogrammierung 20
M Problem Client - Server Sockets: .ready() wird nie true! Netzwerkprogrammierung 6
X Änderung des Objekts wird nicht serialisiert Netzwerkprogrammierung 9
M Socket TCP keep alive Exception wird nicht ausgelöst Netzwerkprogrammierung 11
F getSource Methode wird als Bot erkannt Netzwerkprogrammierung 8
Dit_ RMI setSoTimeout wird ignoriert? Netzwerkprogrammierung 3
J method = PUT, aber ausgeführt wird doGet...? Netzwerkprogrammierung 4
K Was wird genau per Telnet verschickt ? Netzwerkprogrammierung 5
M Dateidownload per FTP wird immer langsamer und bleibt dann stehen Netzwerkprogrammierung 3
J BufferedReader.ready() wird nicht true Netzwerkprogrammierung 10
A Socket BufferedReader.readLine() blockiert bis ein im Socket OutputStream was gesendet wird ... Netzwerkprogrammierung 9
C RMI Klasse wird unter falschem Pfad gesucht Netzwerkprogrammierung 4
B Server-Programm wird durch "read" beendet Netzwerkprogrammierung 8
A Socket Client Server Connection wird aufgebaut aber keine daten geschickt. Netzwerkprogrammierung 5
N Socket Verbindung wird immer verweigert Netzwerkprogrammierung 5
K HTTP-Anfrage an einen Server wird nicht beantwortet Netzwerkprogrammierung 3
M URL Handler wird nicht gefunden Netzwerkprogrammierung 6
L SSL Verbindung aber Server wird erst im Programm festgelegt Netzwerkprogrammierung 4
L Https Verbindung wird aus jar heraus nicht aufgebaut Netzwerkprogrammierung 12
C Download-Fortschritt wird falsch angezeigt. Netzwerkprogrammierung 2
A Quellcode von Homepage wird nicht komplett eingelesen Netzwerkprogrammierung 5
V RMI: code wird einfach übergangen ? Netzwerkprogrammierung 3
A FileChannel+SocketChannel:Datei wird nur teilweise übertrage Netzwerkprogrammierung 4
L RMI-Funktion wird lokal ausgeführt Netzwerkprogrammierung 12
A RMI: Wo wird die Methode ausgeführt? Netzwerkprogrammierung 9
P JNDI LDAP-SSL Verbindung, Zertifikat wird nicht angezeigt ? Netzwerkprogrammierung 2
A JavaMail Problem - Nachricht wird nicht versendet ? Netzwerkprogrammierung 9
T finlalize Methode vom Server wird nicht aufgerufen Netzwerkprogrammierung 4
B Socket wird nicht richtig geschlossen Netzwerkprogrammierung 2
K mapSystemException wird geworfen Netzwerkprogrammierung 2
L Attachment wird nicht angezeigt in der Email Netzwerkprogrammierung 3
P RMI - meine Stub-Class wird nicht gefunden Netzwerkprogrammierung 9
G Socket wird nach Portscann geschlossen Netzwerkprogrammierung 2
R Socket wird nicht ausgeführt Netzwerkprogrammierung 6
L HTTP Restful Webservice Respone mit Null Body Netzwerkprogrammierung 3
E HTTP java.lang.IllegalArgumentException: protocol = http host = null Netzwerkprogrammierung 1
B NetworkInterface.getHardwareAddress liefert null zurück Netzwerkprogrammierung 8
Geese HTML Quelltext auslesen ergibt -null- Netzwerkprogrammierung 2
G Server schickt immer null-Wert Netzwerkprogrammierung 5
R Server gibt "null" aus Netzwerkprogrammierung 2
I Socket empfängt null Netzwerkprogrammierung 3
M ois nicht null, aber ois.getObject liefer exception Netzwerkprogrammierung 3

Ähnliche Java Themen


Oben