Laden...

TCP Client / Server verstehen sich nicht

Erstellt von Tossi65 vor 2 Jahren Letzter Beitrag vor 2 Jahren 1.589 Views
T
Tossi65 Themenstarter:in
83 Beiträge seit 2010
vor 2 Jahren
TCP Client / Server verstehen sich nicht

Hallo Leute,
ich muss zum ersten Mal eine Client/ Server Anwendung erstellen. Der Server ist eine Kameraanwendung, welche wir steuern möchten Dazu gibt es Befehlssequenzen,
die UIT16 sind und an die Kamera gesendet werden sollen.

Ich habe mit C# und SimpleTCPCLient Package einen Client erstellt. Die Programme finden sich auch.
Wenn ich nun folgenden Sequenz sende: 01 00 00 00 (Connect) reagiert die Kamera nicht.
Zum Testen benutze ich YAT und baue dazu eben die gleiche Verbindung auf und wenn ich damit die Sequenz sende reagiert die Kamera.

Zum besseren Verständnis habe ich YAT als Serverinstanz aus meinem 2. Testrechner laufen. Ich benutze die gleichen Einstellungen wie für das Kamerasystem. Ich sende mit dem Client die Sequenz(01 00 00 00) und siehe da, auf dem YAT Server sehe ich 01h 00h 00h 00h.
Sende ich nun vom Server die eigentliche Rückantwort(02 00 00 00) empfange ich auf dem Client 30h 32h 20h 30h 30h 20h 30h 30h 20h 30h 30h ????
Das ist die richtige Antwort aber in Byte eigentlich sollte 02h 00h 00h 00h da stehen.

Ich gehe davon aus, das das selbe Problem mit meinem Client und der Kamera besteht.

Ich brauch dringend Hilfe.

Danke Torsten

Danke Tossi

2.298 Beiträge seit 2010
vor 2 Jahren

Bei TCP/IP Kommunikation werden immer Bytes versendet.

Im allgemeinen solltest du mehr erklären. Wir kennen weder die Spezifikation der Kamera, noch weiß ich persönlich was "YAT" ist.

Wissen ist nicht alles. Man muss es auch anwenden können.

PS Fritz!Box API - TR-064 Schnittstelle | PS EventLogManager |

D
261 Beiträge seit 2015
vor 2 Jahren

Du kannst auch mit Wireshark nachvollziehen welche Netzwerkpakete über deinen PC verschickt werden. Du musst dann lediglich dieses YAT und dein Programm vergleichen.

Wireshark · Go Deep.

T
Tossi65 Themenstarter:in
83 Beiträge seit 2010
vor 2 Jahren

Ja das mit den Bytes beim versenden ist klar.
Hier ein Auszug aus dem Handbuch:

Zitat:
6.1.2 Aufbau einer Nachricht
Die meisten Nachrichtenelemente sind vom Typ UINT16 und bestehen daher aus 2 Bytes. Da Bytes über Ethernet sukzessive und die Nachrichtenelemente im "Little Endian"-Format übertragen werden, wird das niederwertigste Byte zuerst gesendet.

Jede Nachricht beginnt mit der Nachrichten-ID.

Es gibt drei verschiedene Kategorien von Nachrichten:

  1. Nachrichten von BVS Cockpit
    a. Statusnachricht
    b. Ergebniscontainer

  2. Nachrichten an BVS Cockpit ohne Antwort
    a. Disconnect
    b. Zeitstempel setzen
    c. Inputdaten setzen
    d. Ergebnisnummer setzen
    e. Inspektionsprogramm triggern
    f. Inspektionsprogramm starten
    g. Inspektionsprogramm anhalten
    h. Neustart auslösen
    i. Logeintrag schreiben

  3. Nachrichten an BVS Cockpit, die dann nach erfolgter Aktion eine Antwort sendet
    a. Connect
    b. Inspektionsprogramm umschalten
    c. Inspektionsprogramm-ID abfragen
    d. Zeitstempel holen

Alle Nachrichten haben dieselbe Struktur:
Länge in Bytes Struktur Bezeichnung
2 UINT16 Nachrichten-ID
2 UINT16 Nutzdatenlänge in Bytes
Nutzdaten
Nachrichten, die nicht dem vorgegebenen Format entsprechen (falsche Länge, unbekannte Nachrichten-ID), werden
ignoriert.

Connect
Die Connect-Nachricht stellt eine Verbindung her.
Länge in Bytes Struktur Wert Bezeichnung
2 UINT16 01hex Nachrichten-ID
2 UINT16 00hex Nutzdatenlänge in Bytes
BVS Cockpit antwortet darauf mit ihrer Connect-Nachricht.
Länge in Bytes Struktur Wert Bezeichnung
2 UINT16 01hex Nachrichten-ID
2 UINT16 02hex Nutzdatenlänge in Bytes
2 UINT16 02hex Protokollversion
Die folgenden Beispiele zeigen, wie die Nachrichten aufgebaut sind und wie sie übertragen werden.
Die Nachrichten-ID für Connect ist 01hex, als UINT16, "Little Endian": 01hex 00hex
Dann folgt die Nutzdatenlänge. Die Connect-Nachricht hat keine Nutzdaten, die Länge ist Null. Als UINT16 in "Little Endian" wird dies wie folgt übertragen: 00hex 00hex
Da es keine Nutzdaten gibt, ist die Nachricht fertig.
Der gesamte Connect-Befehl sieht folgendermaßen aus:
01hex 00hex
00hex 00hex
In der Programmiersprache C:
unsigned char[] connect =
{
0 x 01, 0 x 00,
0 x 00, 0 x 00
};
Nachricht vom Client an BVS Cockpit: 01 00 00 00
BVS Cockpit antwortet darauf mit: 01 00 02 00 02 00
Disconnect
Mit der Disconnect-Nachricht wird die Verbindung getrennt. Es werden fortan keine Ergebnis-Container und keine Statusnachrichten mehr gesendet; Nachrichten an BVS Cockpit werden ignoriert.
Länge in Bytes Struktur Wert Bezeichnung
2 UINT16 02hex Nachrichten-ID
2 UINT16 00hex Nutzdatenlänge in Bytes
Beispiel:
Nachricht vom Client an BVS Cockpit: 02 00 00 00

Zitat ende

Also wenn ich "01 00 00 00" senden will dann macht der Client daraus "4849324848324848324848" Byte und auf der Serverseitet sehen ich folgendes "30h 31h 20h 30h 30h 20h 30h 30h 20h 30h 30h 01h 00h 00h 00h". Also nicht was ich sehen will. Die FRage dabei ist doch was meinen die mit UInt16 Format!?!?

Danke Tossi

D
261 Beiträge seit 2015
vor 2 Jahren

Zeig doch mal etwas Code wie du z. B. die 01 00 00 00 sendest.

url:
>

YAT ist ja sogar in Csharp geschrieben. Dann schau dir doch einfach an wie die es machen 🙂

T
Tossi65 Themenstarter:in
83 Beiträge seit 2010
vor 2 Jahren

Ach übrigends: YAT ist ein Tool mit dem man Client Server testen und nachstellen kann.
url: https://sourceforge.net/projects/y-a-terminal/

Danke Tossi

2.298 Beiträge seit 2010
vor 2 Jahren

der Client daraus "4849324848324848324848" Byte

Das wäre ein sehr mehrkwürdiger Byte-Wert. Sicher dass du dort nicht irgendwelche ASCII Zeichen liest?

Versuchen wir mal deine Dezimalen Werte die du als "Byte" annimmst in ASCII umzuwandeln.

Dec. 48 = Hex. 30
Dec. 49 = Hex. 31
Dec. 32 = Hex. 20

Insofern scheint ja zumindest das anzukommen, was du auch versendest. Allerdings ist das was du versendest nicht korrekt. Übrigens verschickst du 11 Bytes und nicht wie Eingangs in der Beschreibung angeführt, 2 die du versenden sollst.

Fragst du nämlich mich sollte dein Byte Array das du versendest folgende Werte haben:
1
0

Wissen ist nicht alles. Man muss es auch anwenden können.

PS Fritz!Box API - TR-064 Schnittstelle | PS EventLogManager |

T
Tossi65 Themenstarter:in
83 Beiträge seit 2010
vor 2 Jahren

@dannoe


                    Byte[] bytes;
                    bytes = Encoding.UTF8.GetBytes("01 00 00 00");
                    client.Send(bytes);

Ich habe es auch schon mit AScci.Encoding versucht.

@inflames2k
Da liegst du leider nicht richtig. E§s muss die gesamte Sequenz übermittelt werden "01 00 00 00". Das sind dann mit Blanks 11 Zeichen.

Danke Tossi

D
261 Beiträge seit 2015
vor 2 Jahren

Laut dem Auszug aus deiner Doku darfst du keine Leerzeichen mitschicken:

unsigned char[] connect =
{
0 x 01, 0 x 00,
0 x 00, 0 x 00
};

Also analog in C# mit byte als Typ:


// UInt16
var connectSequence = new byte[] { 0x01, 0x00, 0x00, 0x00 };

Das hier ist übrigens Quatsch, damit wandelst du den Text in die zugehörigen UTF8 Byte Darstellung. Und auch mit ASCII wäre es quatsch. Du sollst Zahlen als Bytes schicken und keinen Text in Bytes umwandeln.


Encoding.UTF8.GetBytes("01 00 00 00");

2.298 Beiträge seit 2010
vor 2 Jahren

@inflames2k
Da liegst du leider nicht richtig. E§s muss die gesamte Sequenz übermittelt werden "01 00 00 00". Das sind dann mit Blanks 11 Zeichen.

Und wo genau steht in der Schnittstellenbeschreibung dass du Zeichen übertragen sollst?

Schon die Beschreibung gibt ja her, dass du da was nicht richtig machst:

  • 2 UINT16 01hex Nachrichten-ID
  • 2 UINT16 00hex Nutzdatenlänge

Rechnet man jetzt mal zusammen, wie viele Bytes das ergibt sind wir bei 4 und nicht bei 11.

Wissen ist nicht alles. Man muss es auch anwenden können.

PS Fritz!Box API - TR-064 Schnittstelle | PS EventLogManager |

D
261 Beiträge seit 2015
vor 2 Jahren

Hier vielleicht etwas verständlicher:


UInt16 messageId = 0x01; // = 1
UInt16 payloadLength = 0x00; // = 0

var messageIdArray = BitConverter.GetBytes(messageId);
var payloadLengthArray = BitConverter.GetBytes(payloadLength);

var connectSequence = new byte[] { messageIdArray[0], messageIdArray[1], payloadLengthArray[0], payloadLengthArray[1] }; // die Arrays könnte man automatisch mergen

T
Tossi65 Themenstarter:in
83 Beiträge seit 2010
vor 2 Jahren

@dannoe

Das geht 😉 super.
Da wäre ich nie drauf gekommen. Die Kamera schickt mir eine Antwort. Diese muss ich nun wieder in einen String zurück wandeln.
😭

Danke Tossi

2.298 Beiträge seit 2010
vor 2 Jahren

Nein du musst gar nichts in einen String umwandeln. Du liest die Bytes und anhand der Werte (Rückumwandlung in UInt16) weißt du, wie die Antwort aussieht.

Was hast denn du die ganze Zeit mit deinen Zeichen / Strings?

Wissen ist nicht alles. Man muss es auch anwenden können.

PS Fritz!Box API - TR-064 Schnittstelle | PS EventLogManager |

4.938 Beiträge seit 2008
vor 2 Jahren

Da wäre ich nie drauf gekommen. Die Kamera schickt mir eine Antwort. Diese muss ich nun wieder in einen String zurück wandeln.

Mir scheint, dir ist nicht so ganz klar, was Binärdaten sind. Die Herangehensweise mit Strings deutet auf eine falsche Vorstellung davon hin.
Du solltest dich daher mal intensiver mit den Basisdatentypen und deren Konvertierungen beschäftigen, gerade wenn du Client-Server-Programmierung (Protokolle) implementieren willst.
Schau dir besonders mal die beiden Klassen BinaryReader und BinaryWriter an, welche dir bei der Implementierung helfen können.

T
Tossi65 Themenstarter:in
83 Beiträge seit 2010
vor 2 Jahren

Danke für eure Hilfe. Ja ich werde mich mal mit Datentypen auseinander setzen. Aber jetzt gibt es wieder neue Probleme.

Danke

Danke Tossi

T
Tossi65 Themenstarter:in
83 Beiträge seit 2010
vor 2 Jahren

Hallo,
hier ein Update: Einfache Befehlssequenzen gehen andere wieder nicht.
Was ich mit Strings habe, hier einen Erklärung:
In einer Datenbanktabelle liegen die Befehlssequenzen als String der Reihe nach vor.
Wenn ich nun an die Kamera etwas schicken will hole ich mir die Befehlssequenzen in der richtigen Reihenfolge,
bearbeite diese wenn nötig (zahlen tauschen JOBID) und will sie dann an die Kamera senden. Wenn die Kamera verstanden hat,
bekomme ich eine Antwort.
Um die Sequenzen umwandeln zu können, lade ich mir diese in ein StringArray gesplittet nach ' '.
Dann mache ich der Reihen nach aus den Einträgen ein UInt16, hole davon mit BitConvert das ByteArray und speichere mir das in eine List<byte[]>.
Die Anzahl der Elemente der List können unterschiedlich sein. Beispiel:01,00,00,00
Jetzt komme ich nicht weiter. WIe mache ich aus der Liste ein passendes Byte ARRAy?????
Der Vorschlag von dannoe:
var connectSequence = new byte[] { messageIdArray[0], messageIdArray[1], payloadLengthArray[0], payloadLengthArray[1] } funktioniert
Beispiel: Sequenz: 01 00 00 00 => 01 00 00 00 funktioniert
Beispiel: Sequenz: 41 00 00 00 => 29 00 00 00 funktioniert nicht
Beispiel: Sequenz: 01 00 00 00 => 02 00 00 00 funktioniert
Beispiel: Sequenz: 31 00 02 00 03 00 => 1F 00 02 00 03 00 funktioniert nicht.

Es macht Spass ist aber auch frustrierend, da natürlich gedrängelt, wann fertig.

Danke Torsten

Danke Tossi

2.298 Beiträge seit 2010
vor 2 Jahren

List<T>.ToArray() ?

Wissen ist nicht alles. Man muss es auch anwenden können.

PS Fritz!Box API - TR-064 Schnittstelle | PS EventLogManager |

T
Tossi65 Themenstarter:in
83 Beiträge seit 2010
vor 2 Jahren

@inflames2k
Hey,
das hatte ich auch gedacht. Aber es ist eine List von byte[].
Bei der ToArray() meckert er rum da es sich um ein Array im Array handelt.

Gruß Torsten

Danke Tossi

4.938 Beiträge seit 2008
vor 2 Jahren

Du hast dich anscheinend die letzten eineinhalb Monate immer noch nicht mit den Grundlagen bzgl. Datentypen auseinandergesetzt.

Warum benutzt du denn überhaupt eine List<byte[]> (anstatt List<byte>)?

Und bei deinen Beispielen erzeugst du anscheinend aus den gegebenen Werten die Hexwerte (z.B. 41 = 0x29).

PS: Dein 3. Beispiel soll wohl eher "Beispiel: Sequenz: 02 00 00 00 => 02 00 00 00 funktioniert" heißen?!

T
Tossi65 Themenstarter:in
83 Beiträge seit 2010
vor 2 Jahren

Danke für Eure Unterstützung.
Ich habe es jetzt hinbekommen.
Manchmal ist man einfach zu blöd für einfache Sachen.
TH69 hatte recht. Man muss lesen was man für Infos bekommt.

Danke

Danke Tossi