Autor |
Beitrag |
jeng
Beiträge: 30
|
Verfasst: Mo 15.06.15 12:49
Ein freundliches Hallo an alle,
Ich habe folgendes problem,
sende einen string an den server bekomme auch antwort und das wars.
Ich muss eine login prozedur senden und dann in diesem "threat" bleiben
um weitere strings oder bytes ausfüren zu können.
Wie kann ich das erledigen?
Währe sehr dankbar für jede hilfe!
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57:
| procedure TForm4.Button1Click(Sender: TObject); var Start: string; Name: string; Pwd: string; Stop: string; X, S, S1, S2: string; a: array[0..20] of Ansichar; I1, I2 : Integer;
begin IdTCPClient1.Host := IP; IdTCPClient1.Port := StrToInt(Form4.Edit2.Text); Start := #$01#$02;
Name := #$55#$53#$45#$52#$3a; s1 := ''; I1:= 21 - Length(Form4.Edit3.Text); S1:= Edit3.Text + StringOfChar(' ', I1); StrPCopy(Versuch.UserID, S1);
Pwd := #$50#$57#$44#$3a; s2 := ''; I2:= 21 - Length(Form4.Edit4.Text); S2:= Edit4.Text + StringOfChar(' ', I2); StrPCopy(Versuch.Passwort, S2);
Stop := #$01#$00;
S := Start+Name+Versuch.UserID+Pwd+Versuch.Passwort+Stop;
if IdTCPClient1.Connected = False then IdTCPClient1.Connect
else Label5.Text := ('Connected'); idTcpClient1.IOHandler.Write(S); try while IdTCPClient1.IOHandler.CheckForDataOnSource(IdTimeoutDefault) do begin end; finally X := IdTCPClient1.IOHandler.InputBufferAsString; Memo1.Lines.add('Version: ' + X); Label6.Text:= X; end; End; |
Moderiert von Martok: Code- durch Delphi-Tags ersetzt
|
|
jeng
Beiträge: 30
|
Verfasst: Mo 22.06.15 08:16
Hallo,
Kann mir keiner hier weiter helfen?
Ich versuche mich mal besser zu erlären.
Ich habe das problem, dass ich an eine electronik verschiedene hex codes senden möchte um relais ein oder auszuschalten.
Nun, über udp klappt das auch ohne probleme.
Nun möchte ich das über tcp erledigen und da komme ich nicht weiter.
Ich sende meine Login daten und bekomme auch die bestätigung zurück dass ich verbunden bin.
Allerdings schickt der server auf einem anderen port diese meldung zurück. Nun bin ich ja verbunden, jetzt schicke ich mein hex folge an den server und da ist das problem, ich bekomme keine antwort mehr weil der den port ja incrementiert hat. So wie ich das vestehe muss ich den port auf dem der server antwortet locken um meine hex sequenz senden zu können. Sonst müsste ich ja jedes mal die login daten plus befehl senden oder wie verstehe ich das?
Ich weiss nich ob ich mich richtig ausdrücke... weiss auch nicht wie ich das in fach jargon benennen kann.
Ich währe dankbar für einen gedanken anstoss...
|
|
Frühlingsrolle
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Mo 22.06.15 12:40
- Nachträglich durch die Entwickler-Ecke gelöscht -
|
|
jeng
Beiträge: 30
|
Verfasst: Mo 22.06.15 13:36
Hallo Frühlingsrolle,
Den serverteil hab ich nicht programmiert, sondern das ist eine IP Karte die Befehle an eine elektronik weiter leitet
um Ports (relais zu schalten) ein oder aus zuschalten.
Also wenn ich diese Hex sequenz sende:
HEX: 01 02 55 53 45 52 3a 61 64 6d 69 6e 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 50 57 44 3a 61 64 6d 69 6e 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 01
Dann bekomme ich diese antwort:
HEX:01 01 56 30 35 36 01
ASCII: \01\01V056\01
Das ist die IP Karte die mit V056 Antwortet.
Damit bin ich verbunden.
Nun kommt das eigentliche problem.
Also ich muss auf dem gleichen port von wo ich die Antwort bekommen hab dann die Hex sequenz senden um den port ein bzw auszuschalten.
Port1 ein HEX: 04 01 02 23 3c 00 0a 01 ff 00 00 00 00 00 00 00 fe
Antwort von der Karte:
HEX: 04 01
ASCII: \04\01
Port1 aus HEX: 04 01 02 23 3c 00 0a 01 00 00 00 00 00 00 00 00 01
Antwort 04 01
ASCII: \04\01
Dieses functionniert aber nur mit der software (screenshot) und auch nur im Presistent TCP mode.
Ich schicke besser ein paar screenshots zum besseren versändnis.
Einloggen, um Attachments anzusehen!
|
|
Narses
Beiträge: 10182
Erhaltene Danke: 1255
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Mo 22.06.15 21:57
Moin und in der EE!
jeng hat folgendes geschrieben : | Ich schicke besser ein paar screenshots zum besseren versändnis. |
Sehr viel hilfreicher wäre eine Beschreibung des Protokolls, dass diese "IP-Karte" nutzt (und zwar am besten direkt vom Hersteller).
Dass sich in einer aktiven TCP-Verbindung der Port ändern sollte, kann ich kaum glauben...
jeng hat folgendes geschrieben : | Ich sende meine Login daten und bekomme auch die bestätigung zurück dass ich verbunden bin.
Allerdings schickt der server auf einem anderen port diese meldung zurück. Nun bin ich ja verbunden, jetzt schicke ich mein hex folge an den server und da ist das problem, ich bekomme keine antwort mehr weil der den port ja incrementiert hat. So wie ich das vestehe muss ich den port auf dem der server antwortet locken um meine hex sequenz senden zu können. |
Wenn du eine aktive TCP-Verbindung hast, dann bleiben die ausgehandelten Ports definitiv fest, bis du diese Verbindung wieder trennst. Das Verhalten, dass du beschreibst, passt auf das Verhalten, dass embedded devices bei UDP-Kommunikation zeigen (btw: warum sollte das denn so schlimm sein mit UDP? idR reicht das error handling in der UDP-Ebene für LAN-Devices doch vollkommen aus). Sowas kann natürlich nicht im "TCP-Mode" auftreten.
Es sei denn: das Device arbeitet nicht verbindungs-, sondern session-orientiert (also wie http), das wäre allerdings extrem ungewöhnlich (und wo sollte dann der Vorteil ggü. einer UDP-Kommunikation sein? ).
Fazit: ohne eine brauchbare Beschreibung des Protokolls, dass da beachtet werden will, wird das nix mit Helfen...
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
jeng
Beiträge: 30
|
Verfasst: Di 23.06.15 10:16
Hallo Narses,
Danke erstmal für die nette Begrüßung.
Also daß ich da was vom Hersteller erwarten kann ist ausgeschlossen.
Ich hab schon mit denen geredet und die geben mir die api nicht heraus.
Die haben einen Server auf dem Adobe Air läuft und man verbindet sich auf diesen, mit einer APP
um die befehle dann an die Karte zu senden.
Was ich vor habe ist, dass ich Ihren Server vermeiden möchte und mich direckt
auf meine installation verbinden möchte.
Also es müsste doch einen weg geben, dass das funktionniert.
Siehe Packetsender, mit dem funktionniert das reibungslos im Persitent TCP mode.
Was ich halt brauchen würde, ist wie sende ich meine Login daten und halte diese verbindung
offen um weitere befehle senden zu können.
Packetsender hatte ja auch keine api der Karte (ist ja nicht dafür geschrieben worden).
Vieleicht würde es mir schon hefen, wenn ich wüßte wie ich eine "Persistent verbindung" herstelle.
Hab auch schon das Internet durchforstet und ich komme da einfach nicht weiter...
Nach was soll ich suchen?
Nennt man "Persistent" vieleicht noch anders?
Hab auch nach beipielen gesucht, aber ich bin nicht fündig geworden.
Naja ich hoffe dass vieleicht einer eine Idee hatt die mir weiter hilft.
mfg
|
|
OlafSt
Beiträge: 486
Erhaltene Danke: 99
Win7, Win81, Win10
Tokyo, VS2017
|
Verfasst: Di 23.06.15 10:39
Du bist noch total in der UDP-Schiene, wo man was an Port:IP schickt und die Verbindung danach automatisch abgebaut wird. Bei manchen Mobilfunk-Providern habe ich dann erlebt, das ein im mobilen Netz befindliches Gerät bei jeder Nachricht (via UDP !) mit einer neuen Portnummer versehen wurde.
Sowas gibts bei TCP nicht, ergo brauchst du auch keine "Verbindung offenhalten". TCP ist eine permanente Verbindung - du machst deinen Connect auf IP:Port und diese Verbindung bleibt so lange offen, bis sie von einem der beiden wieder geschlossen wird. Die gesamte Kommunikation läuft über IP:Port - irgendwelche Portwechsel gibts da nicht.
_________________ Lies, was da steht. Denk dann drüber nach. Dann erst fragen.
|
|
jeng
Beiträge: 30
|
Verfasst: Di 23.06.15 13:37
Hallo OlafSt,
Ok hab verstanden, ich veruch mein Glück.
Ich werde veruchen das pojekt einfach nochmals von vorne auf neu aufzubauen.
Mit minimalen komponenten.
Irgendo muss ich mich da verrannt haben.
Danke an euch alle.
mfg
|
|
jeng
Beiträge: 30
|
Verfasst: Do 23.07.15 20:44
Hallo nochmals,
Also, ich muss troz aller bemühungen mit UDP jetzt auf TCP umbauen.
Verschiedene funktionen meine "Domo Ip Karte" funktionnieren halt nur über TCP.
Nun denn, soweit ich gelesen hab muss ich alles von einander Trennen.
zb.
1 ---> Button verbinden und Login daten Senden.
2 ---> Button fürs Senden.
3 ---> einen Thread der den empfang steuert.
4 ---> Button Trennen.
Gehe ich recht in der Annahme dass Treads das Zauberwort ist?
Wenn Ja, könnte mir da jemand auf die Sprünge Helfen?
Was brauche ich da, wo finde ich das richtige Beispiel Material, vieleicht auch mit Demo Code?
Muss Punkt 2 auch in einem Thread geschehen?
Jede Antwort würde mir sehr Helfen.
Und Bitte ich bin Anfänger.
|
|
Narses
Beiträge: 10182
Erhaltene Danke: 1255
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: So 26.07.15 12:18
Moin!
Da du so explizit darauf hinweist, dass du Anfänger bist, sind IMHO die Indy-Komponenten maximal bedingt geeignet und Multithreading komplett gar nicht. Welche Delphi-Version verwendest du? Hast du die TClientSocket-Komponente in der Palette?
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
jeng
Beiträge: 30
|
Verfasst: Di 28.07.15 14:35
Narses hat folgendes geschrieben : | Moin!
Da du so explizit darauf hinweist, dass du Anfänger bist, sind IMHO die Indy-Komponenten maximal bedingt geeignet und Multithreading komplett gar nicht. Welche Delphi-Version verwendest du? Hast du die TClientSocket-Komponente in der Palette?
cu
Narses |
Hallo,
Ja ich hab XE8 und TClientSocket ist auch installiert!
Ich hab mit einem Chat Multithreating Beispiel rumgetestet, das läuft aber nicht richtig.
Einloggen klappt, verbindung bleibt auch bestehen aber das schalten der relais klappt nicht.
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176: 177: 178: 179: 180: 181: 182: 183: 184: 185: 186: 187: 188: 189: 190: 191: 192: 193: 194: 195: 196: 197: 198: 199: 200: 201: 202: 203: 204: 205: 206: 207: 208: 209: 210: 211: 212: 213: 214: 215: 216: 217: 218: 219: 220: 221: 222: 223: 224: 225: 226: 227: 228: 229: 230: 231: 232: 233: 234: 235: 236: 237: 238: 239: 240: 241: 242: 243: 244: 245: 246: 247: 248: 249: 250: 251: 252: 253: 254: 255: 256: 257: 258: 259: 260: 261: 262: 263: 264: 265: 266: 267: 268: 269: 270: 271: 272: 273: 274: 275: 276: 277: 278: 279: 280: 281: 282: 283: 284: 285: 286: 287: 288: 289: 290: 291: 292: 293: 294: 295: 296: 297: 298: 299: 300: 301: 302: 303: 304: 305: 306: 307: 308: 309: 310: 311: 312: 313: 314: 315: 316: 317: 318: 319: 320: 321: 322: 323: 324: 325: 326: 327: 328: 329: 330: 331: 332: 333: 334: 335: 336: 337: 338: 339: 340: 341: 342:
| unit UClientSimple;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, ExtCtrls, IdStack, IdGlobal;
type TMyRec = record UserID : array[0..20] of Char; Passwort : array[0..20] of Char; end;
type TReceptEvent = procedure (Sender : TObject; Recept : string) of object;
TReceptionthread = class(TThread) private FRecept : string; FIdClient : TIdTCPClient; FOnReception : TReceptEvent; protected procedure Execute; override; procedure DoOnReception; public constructor Create (CreateSuspended : boolean; AIdTCPClient : TIdTCPClient);
property OnReception : TReceptEvent read FOnReception write FOnReception; end;
TFClient = class(TForm) IdTCPClient1: TIdTCPClient; EMessage: TEdit; BConnect: TButton; BSend: TButton; MChat: TMemo; EHost: TLabeledEdit; BDisconnect: TButton; Timer1: TTimer; Button1: TButton; Label1: TLabel; procedure BDisconnectClick(Sender: TObject); procedure BSendClick(Sender: TObject); procedure BConnectClick(Sender: TObject); procedure IdTCPClient1Status(ASender: TObject; const AStatus: TIdStatus; const AStatusText: string); procedure Button1Click(Sender: TObject); procedure DomoSend(); procedure FormCreate(Sender: TObject); procedure Timer1Timer(Sender: TObject);
private FReceptionThread : TReceptionThread; StartTime: TTime;
public procedure ReceptionMessage (Sender : TObject; Recept : string);
end;
var FClient: TFClient; Versuch : TMyRec; IP : String;
implementation
{$R *.dfm}
function StringToHex(S: String): String; var I: Integer; begin Result:= ''; for I := 1 to length (S) do Result:= Result+' '+IntToHex(ord(S[i]),2); end;
function GetRemoteIp(const pHostName: string): string;
begin TIdStack.IncUsage; try Result := GStack.ResolveHost(pHostName); finally TIdStack.DecUsage; end; end;
procedure TFClient.BConnectClick(Sender: TObject); begin MChat.lines.Clear; if GetRemoteIp(EHost.Text) ='' then ShowMessage('L''adresse IP saisie est invalide.') else begin try IdTCPClient1.Connect(EHost.Text, 6355);
FReceptionThread:=TReceptionthread.Create(false,IdTCPClient1); FReceptionThread.OnReception:=ReceptionMessage;
Button1.Enabled := True; BDisconnect.Enabled:=true; BConnect.Enabled:=false; BSend.Enabled:=true; EMessage.Enabled:=true; MChat.Enabled:=true; except ShowMessage('Connection avec le serveur impossible.'); end; end; end;
procedure TFClient.BDisconnectClick(Sender: TObject); begin Timer1.Enabled := False; IdTCPClient1.Disconnect;
Button1.Enabled := False; BDisconnect.Enabled:=false; BConnect.Enabled:=true; BSend.Enabled:=false; EMessage.Enabled:=false; MChat.Enabled:=false; end;
procedure TFClient.BSendClick(Sender: TObject); Var port1on: string;
begin DomoSend(); EMessage.Clear; end;
procedure TFClient.Button1Click(Sender: TObject); var Start: string; Name: string; Pwd: string; Stop: string; X, S, S1, S2: string; a: array[0..20] of Ansichar; I1, I2 : Integer; begin StartTime := Time; Start := #$01#$02;
Name := #$55#$53#$45#$52#$3a; s1 := ''; I1:= 21 - Length('admin'); S1:= 'admin' + StringOfChar(' ', I1); StrPCopy(Versuch.UserID, S1);
Pwd := #$50#$57#$44#$3a; s2 := ''; I2:= 21 - Length('admin'); S2:= 'admin' + StringOfChar(' ', I2); StrPCopy(Versuch.Passwort, S2);
Stop := #$01#$00;
S := Start+Name+Versuch.UserID+Pwd+Versuch.Passwort+Stop; Timer1.Enabled := True; IdTCPClient1.IOHandler.Write(S);
end;
procedure TFClient.FormCreate(Sender: TObject); begin IP := GetRemoteIp(FClient.EHost.Text); end;
Procedure TFClient.DomoSend(); var Buf: TIdBytes; begin
SetLength(Buf, 17); FillBytes(Buf, 17, 0); Buf[0] := $04; Buf[1] := $01; Buf[2] := $02; Buf[3] := $23; Buf[4] := $3c; Buf[5] := $00; Buf[6] := $0a; Buf[7] := $01; Buf[8] := $ff; Buf[9] := $00; Buf[10] := $00; Buf[11] := $00; Buf[12] := $00; Buf[13] := $00; Buf[14] := $00; Buf[15] := $00; Buf[16] := $fe; FClient.IdTCPClient1.IOHandler.Write(Buf, 17); end;
procedure TFClient.IdTCPClient1Status(ASender: TObject; const AStatus: TIdStatus; const AStatusText: string); begin MChat.Lines.Add(AStatusText); end;
procedure TFClient.ReceptionMessage (Sender : TObject; Recept : string); begin MChat.Lines.Add(Recept); end;
procedure TFClient.Timer1Timer(Sender: TObject); begin Label1.Caption := TimeToStr(Time - StartTime); end;
constructor TReceptionThread.Create (CreateSuspended : boolean; AIdTCPClient : TIdTCPClient); begin inherited Create(CreateSuspended); FIdClient:=AIdTCPClient; end;
procedure TReceptionThread.DoOnReception; begin if Assigned(FOnReception) then FOnReception(Self,FRecept); end;
procedure TReceptionThread.Execute; var AByte:array[0..17] of Byte; Count,i: Integer; Value1, Value2 : Integer; Recieve: integer; RBuffer: TIdBytes; RByteBuffer: array of byte; AnsiSTR : String;
begin SetLength(RBuffer, 17); FillBytes(RBuffer, 17, 0);
while FIdClient.connected and not Terminated do
begin FRecept:='';
try FIdClient.IOHandler.CheckForDataOnSource(500); count := FIdClient.IOHandler.InputBuffer.Size;
FIdClient.IOHandler.ReadBytes(RBuffer, FidClient.IOHandler.InputBuffer.Size,False);
SetLength(RByteBuffer, count); Move(RBuffer[0], RByteBuffer[0], count); SetString(AnsiStr, PAnsiChar(@RByteBuffer[0]), Length(RByteBuffer)); if count > 0 then
FRecept:='Got: ' + IntToStr(count) +' bytes ' + Ansistr + ' ' +StringToHex(ansistr);
except Terminate; end;
if FRecept<>'' then Synchronize(DoOnReception);
end; end;
end. |
cu
Jeng
|
|
Narses
Beiträge: 10182
Erhaltene Danke: 1255
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Di 28.07.15 17:23
Moin!
jeng hat folgendes geschrieben : | Ja ich hab XE8 |
Naja, besser als D2 auf jeden Fall...
jeng hat folgendes geschrieben : | und TClientSocket ist auch installiert! |
Gut. Dann schau dir mal das hier an. Wichtig ist, dass die Strings, die du senden/empfangen willst, AnsiStrings sind!
Unterschied zum Indy-TCP-Client: der TClientSocket ist standardmäßig asynchon, liefert also Ereignisse im MainThread-Kontext. Das ist zwar nicht für hohe Datenraten geeignet, aber die hast du auch nicht. Somit sparst du dir das Thread-Gehampel erstmal.
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
jeng
Beiträge: 30
|
Verfasst: Di 28.07.15 22:42
Narses hat folgendes geschrieben : |
Unterschied zum Indy-TCP-Client: der TClientSocket ist standardmäßig asynchon, liefert also Ereignisse im MainThread-Kontext. Das ist zwar nicht für hohe Datenraten geeignet, aber die hast du auch nicht. Somit sparst du dir das Thread-Gehampel erstmal.
|
Ja das stimmt. Das "Thread-Gehampel" ist schon ziemlich schwer zu kappieren. Aber Indy-TCP-Client ist auch für Android und iPhone. TClientSocket leider nicht. Ich schaue es mir trotzdem mal an!
Danke Dir für diese beschreibung.
cu
Jeng
|
|
Narses
Beiträge: 10182
Erhaltene Danke: 1255
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Di 28.07.15 22:46
Moin!
jeng hat folgendes geschrieben : | Aber Indy-TCP-Client ist auch für Android und iPhone. |
Das wage ich stark zu bezweifeln, jedenfalls bis ich mit eigenen Augen eine App gesehen habe, bei der das geht.
Wenn du auf Plattformunabhängigkeit Wert legst, dann mach eine Webanwendung daraus (z.B. mit PHP), das "läuft" dann wirklich auf jedem Endgerät, das einen Browser hat.
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
jeng
Beiträge: 30
|
Verfasst: Mi 29.07.15 07:39
Narses hat folgendes geschrieben : | Moin!
jeng hat folgendes geschrieben : | Aber Indy-TCP-Client ist auch für Android und iPhone. | Das wage ich stark zu bezweifeln, jedenfalls bis ich mit eigenen Augen eine App gesehen habe, bei der das geht.
|
Also ich hatte das ja schon über UDP am laufen, nur halt gehen verschiedene funktionen nicht.
Mit TidTCPClient scheint es auch zu laufen, nur halt schaltet das modul nicht.
cu
Jeng
|
|
|