# Frame übertragen



## kicker13 (5. Okt 2011)

Hallo zusammen!

Als Startinformation: ich verwende eclipse 3.7 (64bit) und windows 7.
Ich möchte einen Frame über die serielle Schnittstelle (RS232) auf einen anderen Computer übertragen.
Der Frame soll als Escapezeichen das x verwenden, sowie Länge und eine CRC-Prüfsumme beinhalten.
xs soll als Startzeichen und xe als Endezeichen verwendet werden.
z.B. xsHallo, wie gehts?xe
Die Buchstaben sollen als eigene Char übertragen werden und nicht als String!

Kann mir dabei jemand helfen? 

Dankeschön im Voraus :toll:


----------



## Marco13 (5. Okt 2011)

Frame ... und dann String? Geht es nur um Text, oder wirklich um den Inhalt eines (J?)Frames als Bild?


----------



## Marco13 (5. Okt 2011)

Das landet im FAQ-Bereich ???:L Hier stimmt doch irgendwas nicht?! ???:L


----------



## SlaterB (6. Okt 2011)

jaja, falsch verschoben 
jetzt in normaler Netzwerkprogrammierung-Area

gemeint ist glaube ich
Frame (networking) - Wikipedia, the free encyclopedia


----------



## Gast2 (6. Okt 2011)

Was erwartest du denn jetzt? Sollen wir den Code für dich schreiben oder was? 

Du hast doch schon gesagt was du machen willst. 

Formattiere dir halt nen String Char Array oder was auch immer so wie du es brauchst und schicks in dein RS232 Interface rein. 

Ich verwende RXTX lib die nimmt String entgegen und wandelt die intern in Bytes zum senden.


----------



## kicker13 (6. Okt 2011)

ja ich meine den Frame in der Netzwerktechnik.

ja fein wäre, wenn mir jemand einen Ansatz zeigen könnte


----------



## Gast2 (6. Okt 2011)

<ironie> klar ich schreibe gerne alles für dich </ironie> 

Tips: 
- String buffer zeichenweise füllen
- Protocolstack für konkretes Protokoll als lib einbinden 
- ...

Da gibts unendlich viele Möglichkeiten. Welche libs nutzt du für serielle Kommmunikation?! 

Was für Anforderungen. Also ein bisschen was musst du schon selber liefern.


----------



## kicker13 (8. Okt 2011)

Ich habs jetzt folgender Maßen gemacht:


```
public class MainApplication {
	// Escape-Zeichen 'l'
	private static final char ESC = 'l';
	// Start of frame
	private static final char SOF = 's';
	// end of frame
	private static final char EOF = 'e';
	// ein Array, das den Frame aufnimmt
	private char[] sendFrame = new char[2000];
	// Länge über den gesamten Frame, 16bit, aber maximal 2000 Zeichen
	// FCS über Länge und gestuffte Message, 16bit
	// Empfangspuffer
	private char[] recFrame = new char[2000];
	// Aktueller Index in recFrame: -1 bedeutet, dass
	// gerade nicht empfangen wird
	private int recIndex = -1;
	// ein Flag, das anzeigt, dass das letzte Zeichen ESC war
	private boolean escSeen = false;
	// Array für den empfangenen Text
	private char[] textArray = new char[2000];

	private JFrame frmKlpmProtokoll;
	/**
	 * @wbp.nonvisual location=66,379
	 */
	private final SerielleSchnittstelle serielleSchnittstelle = new SerielleSchnittstelle();
	private JTextField receiveTextField;
	private JTextField sendTextField;
	private JButton btnSenden;
	private JMenuItem mntmBeenden;
	private JMenuItem mntmDateiSpeichernUnter;
	private JMenuItem mntmDateiffnen;
	/**
	 * @wbp.nonvisual location=251,369
	 */
	private final Timer timer = new Timer(0, (ActionListener) null);

	private void btnSendenActionPerformed(ActionEvent e) {
		String text = sendTextField.getText();
		// Anfang des Frames bilden
		sendFrame[0] = ESC;
		sendFrame[1] = SOF;
		// die Länge lassen wir zuerst einmal aus
		//...
		// jetzt kommt der Text
		int index = 4;
		for (int i = 0; i < text.length(); i++) {
			sendFrame[index++] = text.charAt(i);
			if (sendFrame[index - 1] == ESC) {
				sendFrame[index++] = ESC;
			}
		}
		// Gesamtlänge des Frames
		int length = index + 4;
		// in den Frame schreiben
		sendFrame[2] = (char)((length >> 8) & 0xff);
		sendFrame[3] = (char)(length & 0xff);
		// FCS bilden
		char bcc = 0;
		for (int i = 2; i < index; i++) {
			bcc ^= sendFrame[i];
		}
		// FCS einschreiben
		sendFrame[index++] = (char)((bcc >> 8) & 0xff);
		sendFrame[index++] = (char)(bcc & 0xff);
		// Frameende schreiben
		sendFrame[index++] = ESC;
		sendFrame[index++] = EOF;
		
		// Frame senden
		for (int i = 0; i < index; i++) {
			serielleSchnittstelle.sendByte(sendFrame[i]);
		}
	}
	
	private void myCharacterReceived(CharacterEvent arg0) {
		// das Zeichen, das gerade angekommen ist
		char ch = (char)arg0.getReceivedCharacter();
		System.out.println("Received: <" + ch + "><" + (int)ch + ">");
		// war das letzte Zeichen ein Escape-Zeichen?
		if (escSeen) {
			switch (ch) {
			case SOF: // Start of Frame: mitschreiben
				recFrame[0] = ESC;
				recIndex = 1;
				break;
			case EOF: // End of Frame
				recFrame[recIndex++] = ch;
				checkFrame(recIndex);
				recIndex = -1;
				break;
			case ESC: // es kann ESC selbst sein -> nichts tun
				break;
			default: // das darf eigentlich nicht vorkommen
				System.out.println("Ungültiges Zeichen nach " +
						"ESC empfangen: <" + ch + ">");
				break;
			}
			escSeen = false;
		} else {
			if (ch == ESC) {
				escSeen = true;
			}
		}
		if (recIndex != -1) {
			recFrame[recIndex++] = ch;
		}
	}
	
	private void checkFrame(int length) {
		// Länge aus Frame lesen
		int hb = recFrame[2] & 0xFF;
		int nb = recFrame[3] & 0xFF;
		int recLength = (hb << 8) + nb;
		// und vergleichen
		if (recLength != length) {
			// falsche Länge!
			System.out.println("Ungültige Framelänge: " + recLength +
					" statt " + length);
			return;
		}
		// FCS aus Frame lesen
		hb = recFrame[length - 4] & 0xFF;
		nb = recFrame[length - 3] & 0xFF;
		int recBcc = (hb << 8) + nb;
		// Selber FCS bilden
		char bcc = 0;
		for (int i = 2; i < length - 4; i++) {
			bcc ^= recFrame[i];
		}
		// und vergleichen
		if (recBcc != bcc) {
			// falsche FCS!
			System.out.println("Ungültige FCS: " + recBcc +
					" statt " + bcc);
			return;
		}
		// wenn wir bis hierher gekommen sind, stimmen Länge
		// und FCS -> Text lesen (und destuffen!)
		int index = 0;
		for (int i = 4; i < length - 4; i++) {
			textArray[index++] = recFrame[i];
			if (recFrame[i] == ESC) {
				i++;
			}
		}
		String text = new String(textArray, 0, index);
		receiveTextField.setText(text);
	}
```


----------



## kicker13 (20. Okt 2011)

Das obere funktioniert schon so wie ich es will.

Nun möchte ich aber zusätzlich noch ein Acknowledge mitsenden, welches nach dem Startzeichen eine fortlaufende Nummer mitschickt.
Dieses Acknowledge soll mir der Empfänger zurücksenden und ich überprüfe, ob er das richtige bekommen hat.
Ist es richtig, dann passt es, wenn nicht, dann soll der Frame nocheinmal gesendet werden.

Hat da jemand Ansätze für mich?


----------

