auslesen der ip adresse und der portnummer

Begonnen von salis, 02. Mai 2012, 11:15:26

Vorheriges Thema - Nächstes Thema

0 Mitglieder und 1 Gast betrachten dieses Thema.

salis

hallo,

ich hoffe, es kann mir jemand bei meinem problem helfen.

es sollen daten via tcp/ip an einen client geschickt werden, nachdem vom client eine anforderung an den server geschickt wurde. der server besitzt eine feste ip-adresse und einen festen port. die ip und der port des client sind allerdings unbekannt und werden nur im header übertragen. wie kann ich den header auslesen?

benutze zum senden / empfangen der daten den ip_control baustein

das handshake zwischen client und server findet statt (client baut verbindung zum server auf und dieser bestätigt den aufbau), was ja automatisch durch den baustein erfolgt.

hoffe, die informationen sind ausreichend.

besten dank

peewit

hallo

kannst du etwas genauer erklären warum du diese daten brauchst
wer ist client und wer ist server ?
was machen diese geräte

wenn du nur einen bestimmten client akzeptieren möchtest, dann kann man dies auch beim IP_CONTROL (Server-Mode) vorgeben
aber mir ist noch nicht klar, was du vorhast

prinzipiell:

der Server lauscht auf einem vorgegenenen Port ob ein client sich verbinden möchte
wenn es zum verbindungswunsch kommt, bekommt der server die quell ip und port nummer des clients mitgeteilt und kann darauf reagieren

mittels SysSockAccept- Socketdaten können die Client-Daten herausgefischt werden.


Codeauszug vom IP_CONTROL

TS_OPEN: (* Waiting for incomming connection *)
sockaddr_size := SIZEOF(sockaddr);
socket := SysSockAccept(server_socket, ADR(sockaddr), ADR(sockaddr_size));

IF socket <> SOCKET_INVALID THEN (* neuer Verbindungswunsch vorhanden *)
IF c_mode = BYTE#2 AND sockaddr.sin_addr <> SysSockNtohl(c_ip) THEN (* Mode 2 = TCP + PASSIVE + PORT + IP  auf richtige Partner-IP prüfen *)
state:= C_CLOSE;
ELSE
IF plc_841 OR plc_881 THEN
SysSockSetOption(socket, 6, SOCKET_TCP_NODELAY, ADR(dint_true), SIZEOF(dint_true)); (* Set Push-Bit *)
END_IF;
SysSockIoctl(socket, SOCKET_FIONBIO, ADR(dint_true)); (* NonBlocking mode *)
c_ready := TRUE; (* Connected *)
state := C_WAIT;
END_IF;
ELSIF NOT c_enable THEN (* keine freigabe mehr ? *)
state:= C_CLOSE;
END_IF;
 

salis

so wieder im büro...

die SysSockAccept hatte ich auch schon gefunden. da ich beim test nur fixe adressen und ports benutzt habe, habe ich die rückgabewerte der funktion mit meiner eingestellten ip und port verglichen. beide waren total unterschiedlich.

ich habe mit dann die ip-adresse mal binär dargestellt und habe so sehen können, dass das dword der ip-adresse vertauscht ist. beim ip_control.ip beinhaltet byte 4 "192", byte 3 "168", byte 2 "115" und byte 1 "168". das strukturelement sockaddr.sin_addr beinhaltet byte 4 "168", byte 3 "115, byte 2 "168 und byte 1 "192". und beim port ist es genauso, ebenfalls sind im strukturelement sockaddr.sin_port beide bytes vertauscht. warum weiß ich nicht.

zumindest dürfte ich so das problem in den griff bekommen, dass, wenn ich eine sendeaufforderung durch einen zunächst unbekannten client bekomme, anhand dieser struktur seine adresse und port erfahre.

vielen dank für die schnelle hilfe. der tip mit SysSockAccept reichte schon, um mir die daten mal genauer anzusehen.

peewit

es gibt geräte die verschiedene prozessoren verwenden
diese haben mitunter verschiedene speicherorganisation
Bekannt ist das auch als Big-Endian und Little-Endian

Damit die byte nun nicht undefiniert über netzwerk ausgetauscht werden , hat man sich am medium ethernet auf einen standard geeinigt
aber je nach prozessor müssen die hi/lo byte bzw word verdreht werden, damit die cpu dies auch wieder richtig interpretieren kann

dazu sind solche standrdfunktionen wie  SysSockNtohl etc...
diese werden auf jedem gerät benutzt, und damit werden die verdreher automatisch korrigiert

siehe
http://de.wikipedia.org/wiki/Byte-Reihenfolge

salis

hallo...

ich bräuchte dann noch mal unterstützung. vielleicht verstehe ich auch etwas grundlegendes nicht.

die aufgabe die ich habe besteht darin, dass ich von einem leitrechner (client) einen sendebefehl bekomme (clienent baut zum server eine verbindung auf).

auf dem sütron-panel (server) befindet sich der IP_Control. (IP_C.C_MODE := 4; IP_C.C_OBSERVE := FALSE; IP_C.C_ENABLE := TRUE;).  wenn nun durch dem client eine verbindung aufgebaut wurde, wird der IP_C._C_STATUS = 16#FF. darauf schicke ich mit einem anderen IP_CONTROL daten an den leitrechner(IP_C.C_MODE := 0; IP_C.C_OBSERVE := FALSE; IP_C.C_ENABLE := TRUE;). den port und die ip entnehme ich der struktur sockaddr.

wenn ich den client mit einer anderen steuerung (z.b. xv102 panel von eaton), die ebenfalls mit dem IP_CONTROL arbeitet, simuliere, funktioniert der datentransfer. aber wenn ich zu dem leitstand schicke funktioniert es nicht. vermutlich, weil ich mit dem zweiten IP_CONTROL ebenfalls eine bestätigung des verbindungsaufbaus erwarte. (vielleicht liege ich auch komplett verkehrt)

wie kann ich also realisieren, dass ich (server) dierekt nach dem der client zum server die verbindung aufgebaut hat, ihm daten schicken kann?

ich hoffe mir kann geholfen werden.

peewit

du hast etwas grundlegendes noch nicht verstanden

mit dem ip_control kannst du udp senden/empfangen und tcp senden/empfangen bzw. Client oder Server sein.

der zweite ip_control hat keinen sinn, da der 1. mit dem 2. nichts zu tun hat
jeder für sich baut (wenn möglich) eine eigene datenverbindung auf

wenn du IP_C._C_STATUS = 16#FF bekommst dann ist zwischen client und server schon eine tcp verbindung aufgebaut
ab nun können beide seiten beleibig senden und empfangen

wenn du in den S_BUF.BUFFER[..] daten einträgst und bei S_BUF.SIZE die anzahl der daten werden diese automatisch an die gegenseite versendet

das gleiche passiert wenn die gegenseite daten sendet, dann werden diese im R_BUF.BUFFER[...] eingetragen und R_BUF.SIZE sagt dir wieviele daten vorhanden sind
wenn du die daten verarbeitet hast, musst du R_BUF.SIZE = 0 machen

du solltest dir den quellcode diverser network bausteine ansehen, um zu lernen wie man damit umgeht


salis

mir ist bekannt, dass ich noch viel lernen muss. dieser bereich ist absolutes neuland für mich. habe dieses programm übernommen und bin davon ausgegengen, dass man es auf diesem weg machen muss.

trotzdem vielen dank für deine hilfe

newbie

salis

der newbie hat noch eine frage.

ich habe jetzt das programm aufgebaut, wie von dir beschrieben (code ist im anhang). ich simuliere den client mit TCP Client.exe. die verbindung wird aufgebaut und ich schicke vom server anschließend 29 datenpakete. die beschriebenen bytes werden im fenster vom TCP Client aufgelistet (screenshot im anhang). wenn ich mit wireshark mitlogge (screenshot im anhang), wird als protokoll der verbindung X11 angegeben. (laut wiki dient dieses protokoll zum aufbau von grafischen benutzeroberflächen). die geloggten bytes enthalten trotzdem den inhalt, der vom server übertragen wird. allerdings kann der kunde mit seiner software dieses x11 protokoll nicht verarbeiten.

waran kann es liegen, dass mit diesem typ geschickt wird? wie kann man abhilfe schaffen?

// benutze als server jetzt eine wago 750-841

[gelöscht durch Administrator]

peewit

#8
hallo

du verwendest den port 6000
port 6000 wird normalerweise verwendet vom x11 protokoll (X-Server)
darum zeigt wireshark die kommunikation über port 6000 als X11 an
mehr ist da nicht dran !
trotzdem kannst du diesen port 6000 frei benutzen solange beide seiten die gleiche sprache reden !

du must mehr details erzählen
was sollen den client und server miteinander austauschen, gibt es ein standard protokoll oder werden nur bytes hin und hergeschickt



deine angehängten dateien sind teilweise nicht hilfreich

der baustein ist nur ein ausschnittt vom ganzen (der exportierte baustein wäre schon viel besser)
die wireshark grafik ist nichtssagend, da musst du bitte immer die wireshark datei posten, ansonsten ist dies ziemlich wertlos !

was zumindest auffällt ist das senden..... so wird das nichts

Daten nur einmal  eintragen !
der rest passiert von selber , wenn natürlich vorher die verbindung ausgebaut wurde !

IF xSendeWunsch THEN
  xSendeWunsch := FALSE;
  S_BUF.BUFFER[0] := BYTE#01;
  S_BUF.BUFFER[1] := BYTE#02;
  S_BUF.BUFFER[2] := BYTE#03;
  S_BUF.BUFFER[3] := BYTE#04;
  S_BUF.BUFFER[4] := BYTE#05;
  S_BUF.SIZE := 5;
END_IF;


sobald S_BUF.SIZE = 0 ist wurden alle daten versendet