Entwickler-Ecke
Open Source Projekte - TUdpSockUtil v2.01 - Alternative zum Indy-UDP-Client/Server
Narses - Fr 03.02.06 01:29
Titel: TUdpSockUtil v2.01 - Alternative zum Indy-UDP-Client/Server
Der
TUdpSockUtil ermöglicht die einfache Kommunikation über das UDP-Protokoll (UDP-Client/Server-Socket) und ist damit praktisch gleichwertig zu einem
IdUdpServer und
IdUdpClient in einer schlanken Komponente. Die Benutzung ist an
TClientSocket bzw.
TServerSocket angelehnt, so dass jemand, der gewohnt ist mit den Sockets umzugehen, keine großen Probleme damit haben sollte.
Die Komponente kann im Register "Internet" (da, wo normalerweise auch die Socket-Komponenten drin sind) installiert werden. Natürlich kann die Komponente auch dynamisch erzeugt werden, wenn die Installation in der IDE nicht gewünscht ist.
Grober Funktionsumfang:
- Senden und Empfangen von UDP-Paketen als String oder über einen Buffer (wie .SendText() bzw. .SendBuf() und .ReceiveText() bzw. .ReceiveBuf() bei den Socket-Komponenten)
- Benachrichtigung beim Empfang eines UDP-Paketes, bei Sendebereitschaft oder eines Fehlers per Ereignismethode
- Einfaches Senden von Broadcasts (Nachrichten an alle Hosts im Netzwerk)
- Einfache Handhabung durch Integration in die Komponentenpalette der IDE
- Neu ab v2.x: Ansteuerung von UDP-Port-spiegelnden Microcontrollern ist endlich möglich!
Eine ausführliche Anleitung, wie man die Komponente installiert, sowie eine sehr ausführliche Dokumentation dieser und der Quelltext gleich mit, befindet sich im Projaktarchiv im Anhang.
Neu: Dazu gibt es noch mehrere Beispielprogramm mit Source: Mini-UDP-Chat, UDP-Chat mit Flüstern, Micro-Controller Ansteuerung, AutoLocalPort-Demo.
In diesem Zusammenhang:
Wer ohne sich durch die Doku-Seiten "durchzuarbeiten" :les: :zwinker: wissen will, was diese Komponente "kann", sollte sich mal die fertige Demoprogramme im Projektarchiv ansehen bzw. ausprobieren, am besten auf mehreren PCs im LAN gleichzeitig. Hier ein Codebeispiel, um schon mal abschätzen zu können, wie einfach die Benutzung ist:
Delphi-Quelltext
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:
| uses ..., WinSock; procedure TForm1.BtnSendClick(Sender: TObject); begin UdpSockUtil1.RemoteHost := RemoteHost.Text; UdpSockUtil1.RemotePort := StrToIntDef(RemotePort.Text,12345); UdpSockUtil1.SendText(Input.Text); end;
procedure TForm1.BtnBroadcastClick(Sender: TObject); begin UdpSockUtil1.RemotePort := StrToIntDef(RemotePort.Text,12345); UdpSockUtil1.BroadcastText(Input.Text); end;
procedure TForm1.UdpSockUtil1Receive(Sender: TObject); var Msg: String; vonIP: in_addr; begin Msg := UdpSockUtil1.ReceiveText(vonIP); ShowMessage(IntToStr(Length(Msg))+#13+Msg+#13+inet_ntoa(vonIP)); end; |
History:
v1.00 vom 03.02.2006
- erste öffentliche Version
v1.01 vom 23.02.2010
- Anpassung an Unicode-Delphi-Versionen
v2.01 vom 13.03.2012
- Milestone-Release, Details in der PDF-Doku im Archiv
Kommentare zu der Komponente sind hier durchaus erwünscht.
cu
Narses
Xantor - Di 07.03.06 15:14
Also - so wie ich es in einem ersten Test sehe, funktioniert das ganz ausgezeichnet. Übrigens, das Sync-Problem etc. taucht mit diesen Komponenten nicht auf. Jedes Packet wird gesendet und auch empfangen und das ganze ohne nennenswerte Latenz. Allerdings taucht nach rund 24000 Bytes ein Fehler auf - ich sende per Broadcast und da werden nicht alle Bytes von allen Rechnern abgeholt - oder liegt das am Sender?
Fehlermeldung: "Ein Socketvorgang konnte nicht ausgeführt werden, da dem SystemPufferspeicher fehlt oder eine Warteschlange voll war (10055), auf API'Bind' "
Hast du da auf anhieb eine Idee, was ich da falsch mache?
Basti2k - Di 07.03.06 15:55
Titel: Probleme mit falschem Host
Hallo, ich habe ein Problem. Stellt man mit der UdpSockUtil eine Verbindung zu einem Host her den es nicht gibt, kann man ohne neustarten des Programms keine Verbindung zu einem exsistierenden Host herstellen. Ich wüste auch nicht wie man das umgehen könnte. Ihr vieleicht?
thx
Xantor - Di 07.03.06 17:31
Ich glaub meinen Fehler hab ich gefunden: CloseInactiveSockets muß TRUE sein.
Narses - Di 21.03.06 01:26
Moin!
Xantor hat folgendes geschrieben: |
Allerdings taucht nach rund 24000 Bytes ein Fehler auf - ich sende per Broadcast und da werden nicht alle Bytes von allen Rechnern abgeholt - oder liegt das am Sender?
Fehlermeldung: "Ein Socketvorgang konnte nicht ausgeführt werden, da dem SystemPufferspeicher fehlt oder eine Warteschlange voll war (10055), auf API'Bind' "
Hast du da auf anhieb eine Idee, was ich da falsch mache? |
Ohne etwas mehr von deinem Quelltext zu sehen, kann ich nicht viel dazu sagen; deiner Beschreibung nach kann ich keinen "Fehler" erahnen... :gruebel: :wink:
Basti2k hat folgendes geschrieben: |
Hallo, ich habe ein Problem. Stellt man mit der UdpSockUtil eine Verbindung zu einem Host her den es nicht gibt, kann man ohne neustarten des Programms keine Verbindung zu einem exsistierenden Host herstellen. |
Da es sich um UDP handelt (verbindungsloses Protokoll), kann man gar keine "Verbindungen" in diesem Sinne herstellen. Vielleicht solltest du dir mal das LAN-Chat-Tut ansehen. :wink: Zeig doch mal etwas von deinem Quelltext, dann kann ich möglicherweise auch mehr dazu sagen. Ein entsprechendes Verhalten konnte ich in meinen Tests nicht nachvollziehen.
cu
Narses
Xantor - Di 21.03.06 19:07
Wie gesagt: CloseInactiveSockets muß TRUE sein - dann funktioniert alles wunderbar
hui1991 - Mi 10.05.06 18:40
Bei mir fehlt die RTLConsts.
Woher bekomme ich sie?
Narses - Mi 10.05.06 21:57
Moin!
Welche Delphi-Version hast du denn? Sollte eigentlich dazugehören... ? :?
cu
Narses
hui1991 - Do 11.05.06 13:16
In Delphi 2005 kann ich so wie in der Anleitung das nicht installieren und in Delphi 5 fehlt RTLConsts. Liegt warscheinlich am Delphi 5.
Narses - Do 11.05.06 13:59
Moin!
Füg
das in der
TUdpSockUtil.pas ein, dann kannst du das
uses RTLConsts; rausnehmen:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| [...] uses Windows, Messages, SysUtils, Classes, WinSock, SyncObjs;
resourcestring sWindowsSocketError = 'Windows-Socket-Fehler: %s (%d), auf API ''%s'''; sCannotCreateSocket = 'Es kann kein neuer Socket erzeugt werden';
const USU_WM_ASYNCSELECT = WM_USER +4711; [...] |
cu
Narses
hui1991 - Do 11.05.06 14:53
Ich hab nur noch fehler:
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9:
| [Warnung] UdpSockUtil.pas(230): Konstantenausdruck verletzt untere Grenzen [Fehler] UdpSockUtil.pas(263): Undefinierter Bezeichner: 'DeallocateHWnd' [Fehler] UdpSockUtil.pas(301): Undefinierter Bezeichner: 'AllocateHWnd' [Fehler] UdpSockUtil.pas(301): Nicht genügend wirkliche Parameter [Warnung] UdpSockUtil.pas(373): Konstantenausdruck verletzt untere Grenzen [Warnung] UdpSockUtil.pas(387): Der Vergleich ergibt immer Falsch [Warnung] UdpSockUtil.pas(406): Der Vergleich ergibt immer Falsch [Warnung] UdpSockUtil.pas(496): Konstantenausdruck verletzt untere Grenzen [Fataler Fehler] dclusr50.dpk(34): Verwendete Unit 'UdpSockUtil.pas' kann nicht compiliert werden |
So ich hoffe das funktioniert bald, ich stehe grad im Stillstand...
...kann in moment nix anderes machen als die Komponete versuchen zu installieren.
Narses - Do 11.05.06 18:07
Moin!
Hm, ich hab unterhalb von D6 praktisch keine Erfahrung... :? Was spricht dagegen D7 zu nehmen? ;)
Quelltext
1: 2:
| [Fehler] UdpSockUtil.pas(263): Undefinierter Bezeichner: 'DeallocateHWnd' [Fehler] UdpSockUtil.pas(301): Undefinierter Bezeichner: 'AllocateHWnd' |
Nimm halt mal das "Classes." weg und schau, ob der Compiler die Referenzen selbst auflösen kann.
cu
Narses
hui1991 - Do 11.05.06 20:03
Keine Lust mehr ich besorge mir D7
D5 ist denke ich zu alt. Es wurde ja auch mit D7 getestet.
Es hat dort geklappt.
Weil so komm ich mit meinem Programm net weiter. :cry:
Narses - Do 22.06.06 14:22
Moin!
Da die Frage aufkam: "
Wie kann ich die Portnummer des Absenders ermitteln?", hier der Ansatz, um diese Information abzugreifen.
Im Quelltext der Komponente steht diese Information beim Lesen aus dem WSA-Puffer bereit, allerdings wird die Portnummer nicht nach Aussen weitergegeben (da die Information sehr selten sinnvoll verwendbar ist):
Delphi-Quelltext
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:
| function TUdpSockUtil.ReceiveBuf(var Buf; BufSize: Integer; var RemoteAddr: in_addr; Flags: Integer = 0): Integer; var FromAddr: TSockAddrIn; FromAddrLen: Integer; ErrorCode: Integer; RemotePort: Integer; begin FSocketLock.Enter; try Result := 0; RemoteAddr.S_addr := -1; if (FRecvSock <> INVALID_SOCKET) then begin FromAddrLen := SizeOf(FromAddr); ZeroMemory(@FromAddr,FromAddrLen); Result := WinSock.RecvFrom(FRecvSock,Buf,BufSize,Flags,FromAddr,FromAddrLen); if (Result = SOCKET_ERROR) then begin ErrorCode := WSAGetLastError; Result := 0; if (ErrorCode <> WSAEWOULDBLOCK) then if Assigned(FOnError) then begin FOnError(Self,ErrorCode); Abort; end else raise EUSUError.CreateResFmt(@sWindowsSocketError, [SysErrorMessage(ErrorCode), ErrorCode, 'RecvFrom']); end else begin RemoteAddr := FromAddr.sin_addr; RemotePort := ntohs(FromAddr.sin_port); end; end; finally FSocketLock.Leave; end; end; |
Mit den markierten Zeilen lässt sich die Portadresse ermitteln. Für die Übergabe nach Aussen stehen zwei Ansätze zur Verfügung:
a) Einen weiteren var-Parameter Port: Integer in der Funktionsdeklaration einfügen, oder
b) nicht in_addr, sondern TSockAddrIn als Remote-var-Parameter nehmen, dann wird alles zurückgeliefert.
cu
Narses
oern - Sa 24.06.06 13:15
Erstmal muss ich loswerden das das die beste netzwerk komponente ist mit der ich je gearbeitet habe :)
Zur zeit versuche ich damit eine record zu versenden, dabei kommt aber die fehler meldung "Windows Socket Fehler: 10014 Ungültige zeiger adresse" diese meldung kann mich mir leider nicht erkären :(
Ich hoffe hier kann mir jemand helfen.
Hier meine Klasse:
Delphi-Quelltext
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:
| unit uglsn_engine;
interface
uses UdpSockUtil, SysUtils, Classes, IdIPWatch, Dialogs;
const GLSN_DEFAULTPORT = 42768; GLSN_STR = 0; GLSN_POS = 1;
type TGLS_IPString = string[18]; TGLS_SString = string[20]; TGLS_LString = string[255]; TGLS_Point = packed record X, Y, Z: Double; end;
type TGLS_NetSend = packed record C: Integer; K: Integer; P: Integer; Name: TGLS_SString; case Integer of 0:( M1, M2, M3, M4, M5: TGLS_SString; ML: TGLS_LString; ); 1:( Pos: TGLS_Point; Dir: TGLS_Point; Speed: Double; Power: Double; ); end;
type TGLS_OnReceiveEvent = procedure(r: TGLS_NetSend;ip: string) of object; TGLS_Network = class (TUdpSockUtil) protected IP: TIdIPWatch; FOnRecieveRecord: TGLS_OnReceiveEvent; procedure Receive(Sender: TObject); public constructor Create(AOwner: TComponent); override; procedure BroadcastRecord(r: TGLS_NetSend); procedure SendRecord(r: TGLS_NetSend); published property OnReceiveRecord: TGLS_OnReceiveEvent read FOnRecieveRecord write FOnRecieveRecord; end;
implementation
uses WinSock;
procedure TGLS_Network.BroadcastRecord(r: TGLS_NetSend); var s: string; begin Move(r, s, sizeof(TGLS_NetSend)); Self.BroadcastText(s); end;
constructor TGLS_Network.Create(AOwner: TComponent); begin inherited; IP:= TIdIPWatch.Create(self); IP.HistoryEnabled:= false; Self.OnReceive:= Receive; Self.LocalPort:= GLSN_DEFAULTPORT; Self.RemotePort:= GLSN_DEFAULTPORT; Self.Listen:=true; end;
procedure TGLS_Network.Receive(Sender: TObject); var Len: Integer; Msg: String; vonIP: in_addr; r: TGLS_NetSend; begin Len := Self.ReceiveLength; if (Len > 0) then begin Msg := Self.ReceiveText(vonIP); if inet_ntoa(vonIP)<>IP.LocalIP then begin if Len=sizeof(TGLS_NetSend) then begin if Assigned(FOnRecieveRecord) then begin Move(msg, r, sizeof(TGLS_NetSend)); FOnRecieveRecord(r, inet_ntoa(vonIP)); end; end; end; end; end;
procedure TGLS_Network.SendRecord(r: TGLS_NetSend); var s: string; begin Move(r, s, sizeof(TGLS_NetSend)); Self.SendText(s); end;
end. |
und der demo aufruf:
Delphi-Quelltext
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:
| unit uglsn_demo;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, uglsn_engine, StdCtrls;
type TGLSNWindow = class(TForm) Button1: TButton; procedure FormCreate(Sender: TObject); procedure Button1Click(Sender: TObject); private public n:TGLS_Network; procedure Receive(r: TGLS_NetSend; ip: string); end;
var GLSNWindow: TGLSNWindow;
implementation
uses WinSock;
{$R *.dfm}
procedure TGLSNWindow.FormCreate(Sender: TObject); begin n:=TGLS_Network.Create(self); n.OnReceiveRecord:= Receive; end;
procedure TGLSNWindow.Receive(r: TGLS_NetSend; ip: string); begin case r.K of GLSN_STR:showmessage(r.ML); GLSN_POS:; end; end;
procedure TGLSNWindow.Button1Click(Sender: TObject); var r: TGLS_NetSend; begin n.BroadcastRecord(r);end; |
mfg, Björn
Edit hab das Problem gelöst, jetz klappt es mit records:
Delphi-Quelltext
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:
| interface
uses SysUtils, Classes, IdBaseComponent, IdComponent, IdIPWatch, UdpSockUtil, WinSock, Forms, Dialogs;
const ALL = '255.255.255.255'; GLSN_DEFAULTPORT = 42768; GLSN_STR = 0; GLSN_POS = 1;
type TGLS_IPString = string[18]; TGLS_SString = string[20]; TGLS_LString = string[255]; TGLS_Point = packed record X, Y, Z: Double; end;
type TGLS_NetSend = packed record C: Integer; K: Integer; P: Integer; Name: TGLS_SString; case Integer of 0:( M1, M2, M3, M4, M5: TGLS_SString; ML: TGLS_LString; ); 1:( Pos: TGLS_Point; Dir: TGLS_Point; Speed: Double; Power: Double; ); end;
type TGLSN_Exception = Exception; TGLS_OnReceiveEvent = procedure(r: TGLS_NetSend;ip: string) of object; TGLSN_Engine = class(TDataModule) UdpSockUtil: TUdpSockUtil; IP: TIdIPWatch; procedure UdpSockUtilError(Sender: TObject; Error: Integer); procedure UdpSockUtilReceive(Sender: TObject); procedure DataModuleCreate(Sender: TObject); protected FOnRecieveRecord: TGLS_OnReceiveEvent; public Eceptions: boolean; procedure BroadcastRecord(r: TGLS_NetSend); procedure SendRecord(r: TGLS_NetSend; toip: string); published property OnReceiveRecord: TGLS_OnReceiveEvent read FOnRecieveRecord write FOnRecieveRecord; end;
var GLSN_Engine: TGLSN_Engine;
implementation
{$R *.dfm}
procedure TGLSN_Engine.UdpSockUtilError(Sender: TObject; Error: Integer); begin if Eceptions then TGLSN_Exception.Create('GLSN Socket Error: '+inttostr(Error)); end;
procedure TGLSN_Engine.UdpSockUtilReceive(Sender: TObject); var Len: Integer; Msg: String; vonIP: in_addr; buffer: TGLS_NetSend; begin Len := UdpSockUtil.ReceiveLength; if (Len > 0) then begin UdpSockUtil.ReceiveBuf(buffer, sizeof(buffer), vonIP); if inet_ntoa(vonIP)<>IP.LocalIP then begin if Assigned(FOnRecieveRecord) then begin FOnRecieveRecord(buffer, inet_ntoa(vonIP)); end; end; end; end;
procedure TGLSN_Engine.DataModuleCreate(Sender: TObject); begin UdpSockUtil.Listen:=true; end;
procedure TGLSN_Engine.BroadcastRecord(r: TGLS_NetSend); var s: string; begin s:=UdpSockUtil.RemoteHost; UdpSockUtil.RemoteHost:=ALL; UdpSockUtil.SendBuf(r, sizeof(r)); UdpSockUtil.RemoteHost:=s; end;
procedure TGLSN_Engine.SendRecord(r: TGLS_NetSend; toip: string); var s: string; begin s:=UdpSockUtil.RemoteHost; UdpSockUtil.RemoteHost:=toip; UdpSockUtil.SendBuf(r, sizeof(r)); UdpSockUtil.RemoteHost:=s; end;
end. |
oern - So 25.06.06 11:47
Zitat: |
Ich möchte allerdings unter Hinweis auf diesen FAQ-Beitrag davon abraten, records zu versenden. |
Gut, leider sind meine Netzwerk kennise dermaßen gering das ich mich jetzt freue das es klappt, und da ich keine records mit dyn typen verwende trit problem 1 nicht ein, an problem 2 kann ich jedoch nichts machen, erst mal jedenfalles, also werde ich bei meiner lösung bleiben solage sie funktioniert, und mein modul verändern sobald es nötigt wird, aber danke für den Hinweis.
mfg, Björn
freedy - Mo 26.06.06 08:54
Auch wir nutzen die Komponente. Uns gefällt vor allem, dass sie so klein und schlank ist.
Das Versenden von Records macht uns keine Probleme. Durch einen fest definierten Header, den wir jedem UDP-Paket vorwegstellen, umgehen wir das Problem, irgendwo mal Datensalat zu bekommen.
Inzwischen habe ich eine weitere Klasse abgeleitet, die sogar einen Handshake ermöglicht und Daten, die auf mehrere Pakete aufgeteilt wurden, wieder zusammensetzt. Warum das Ganze wo es doch TCP gibt? :-) Fragt meinen Chef. Ich mache schließlich auch nur, was mir gesagt wird. ;-)
Narses - Mo 26.06.06 10:48
Moin!
freedy hat folgendes geschrieben: |
Auch wir nutzen die Komponente. Uns gefällt vor allem, dass sie so klein und schlank ist. |
Nochmal Danke. :D
freedy hat folgendes geschrieben: |
Das Versenden von Records macht uns keine Probleme. Durch einen fest definierten Header, den wir jedem UDP-Paket vorwegstellen, umgehen wir das Problem, irgendwo mal Datensalat zu bekommen. |
Das Problem liegt leider genau an dieser Stelle: wer noch nie auf Grund von unvorhersehbaren Anforderungen seine "festen Definitionen" wieder gelöst hat, der "werfe das erste Record" (mal frei philosophiert ;)).
cu
Narses
oern - Fr 30.06.06 20:37
Hi,
Ich habe noch eine Frage zur Komponente, ich habe oben im Quelltext gelesen das die maximale Paketgröße 512 byte ist. Was passiert nun wenn ich jetzt ein sagen wir 393 Byte großes Paket sende. Werden dann nur 393 Byte gesendet oder 512 Byte ?
mfg, Björn
Narses - Fr 30.06.06 22:28
Moin!
oern hat folgendes geschrieben: |
Werden dann nur 393 Byte gesendet |
Yip, plus UDP-Protokoll-Overhead von ein paar Bytes.
cu
Narses
GlobalImpact - Do 27.07.06 16:32
Hi,
bin grad auf den Beitrag gestoßen.
Habs ordnungsgemäß installiert, nur bei mir wird ein Fehler angezeigt:
Undefinierter Bezeichner "in_addr"
Und zwar jetz konkret, wenn ich das UPDRecieve Erigniss benutze.
Edit:
Hab Delphi 2005 PE
Danke für die Antwort
mfg GlobalImpact
Fighter#1 - Do 27.07.06 16:36
Winsock muss bei uses eingebungen werden
PlugnPray - So 30.07.06 09:51
Kann mir mal einer bitte sagen, wie ich es unter Delphi 2005 zum Laufen kriege?
Die Installation bezieht sich ja nur auf Delphi 7, aber in 05 nimmt es die Dateien nicht an.
Danke.
Fighter#1 - So 30.07.06 10:12
Einfach in den Delphi 2005 Hauptordner (nicht Bin) packen, oben einbinden dann in Private oder Public einbinden, hier ein Bsp:
Delphi-Quelltext
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:
| uses ...,UDPSockUtil,Winsock;
type
... procedure UdpSockUtil1Receive(Sender: TObject);
... private udp:TUDPSockUtil;
...
udp:=TUDpSockutil.Create(self); udp.Name:='Udp1'; udp.LocalPort:=2555; udp.Listen:=True; udp.OnReceive:=Form1.UdpSockUtil1Receive;
...
procedure TForm1.UdpSockUtil1Receive(Sender: TObject); var Msg: String; vonIP: in_addr; begin Msg := Udp.ReceiveText(vonIP); ShowMessage(Msg); end; |
PlugnPray - So 30.07.06 10:34
Danke schön, das ging fix :)
Fighter#1 - So 30.07.06 17:45
Keiner wartet gern ...
redjustice - Sa 19.08.06 11:59
Hey!
Kurz eine Frage, ich checke das UDP Protokoll noch nicht so ganz zu 100%...
Kann man auch Broadcast's ins Internet senden?
Oder ist sowas nur im lokalen Netzwerk möglich?
Thx!
MfG red
Fighter#1 - Sa 19.08.06 13:15
Geht auch im Internet, aber nur bei einem Bestimmten Address bereich in dem du bist.
Ich glaub die Internetprovider ham so ihre eigenen Addressbereiche ...
Narses - Sa 19.08.06 23:05
Moin!
redjustice hat folgendes geschrieben: |
Kann man auch Broadcast's ins Internet senden?
Oder ist sowas nur im lokalen Netzwerk möglich? |
Faktisch geht das nur im LAN, da die Provider UDP-Broadcasts fast immer filtern. (Macht auch durchaus Sinn, da sonst die Netzbelastung unnütz stark ansteigt...)
Allerdings kannst du problemlos UDP-Pakete über das Internet an bestimmte IP-Adressen versenden.
cu
Narses
freedy - Fr 25.08.06 13:55
Hallo Narses!
Ich bin heute auf folgendes Problem gestoßen. Meine Delphi Entwicklungsumgebung hat eine Verbindung zu dem PC aufgenommen, der mir alle halbe Sekunde ein UDP-Paket schickt. Jetzt hat BDS2006 auch den Port belegt, der zum Abhören gedacht war. Finde ich total merkwürdig.
Seitdem läuft meine Anwendung jedenfalls nicht mehr unter der IDE. Dabei bin ich darauf gestoßen, dass noch keine Funktion gibt, die prüft, ob der Port überhaupt frei ist. Kann man (du ;-) ) das noch einbauen?
PS: Sollte jemand wissen, wie ich die Verbindung, die BDS2006 aufgebaut hat, wieder kappen kann, bitte ich um Nachricht!!!
Narses - Fr 25.08.06 15:04
Moin!
freedy hat folgendes geschrieben: |
Meine Delphi Entwicklungsumgebung hat eine Verbindung zu dem PC aufgenommen |
:shock: Warum sollte denn eine IDE(!) selbstständig(!) eine UDP-Verbindung aufbauen... :nixweiss: :gruebel: :?
freedy hat folgendes geschrieben: |
Jetzt hat BDS2006 auch den Port belegt, der zum Abhören gedacht war. Finde ich total merkwürdig. |
Allerdings, da stimmt doch was nicht... :|
freedy hat folgendes geschrieben: |
noch keine Funktion gibt, die prüft, ob der Port überhaupt frei ist. Kann man (du ;-) ) das noch einbauen? |
Ist doch schon drin. Die Methode .Listen erzeugt dann einen Fehler, den du entsprechend behandeln kannst (WSA-Code weiß ich gerade nicht, lass ihn dir doch einfach im OnError ausgeben ;)).
cu
Narses
freedy - Fr 25.08.06 17:13
Stimmt. Auf die Fehlerbehandlung bin ich inzwischen auch schon gekommen.
Aber die IDE macht mir wirklich Sorgen. Mit einem Mal meldete die Firewall, dass besagter Rechner eine Verbindung mit BDS haben will. Gut, habe ich blockiert. Dann ging gar nichts mehr.
"netstat -ano" sagt mir, dass der Port jetzt immer von Delphi belegt ist. Warum? Keine Ahnung. Ich erkläre mir das damit, dass das BDS ja auch Nachrichten von Borland empfängt. Vielleicht lernt es ja und wenn Nachrichten zufällig auf einem Port ankommen, wird der für zukünftige auch reserviert.
Starte ich meine Anwendung zuerst und dann das BDS semmelt das total ab mit Pointerverletzungen etc. Es lässt sich dann auch nicht mehr beenden. Tja. Montag schauen wir dann mal weiter.
Ein schönes Wochenende.
Force - Fr 15.09.06 19:22
hey, ich hab ein kleines Problem mit dem UDPSockUtil:
Ich habe einen Procedure, die aufgerufen wird, wenn man einen Button klickt oder ein timer einsetzt. Die Procedure soll an alle Server in einer Liste neun Bytes senden, wenn der Server online ist, sollte eine 166-Byte-Antwort kommen. Allerdings funktioniert die Procedure nur beim ersten Aufruf. Ab dem zweiten Aufruf sendet UDPSOckutil (so weit ich weiß) alle Anfragen nur an einen Server und empfängt nichts mehr (auch wenn die Anfragen an den richtigen Server gesendet wurden).
Hier ist der Quelltext, wär super, wenn jemand mir helfen könnte....
Delphi-Quelltext
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:
| procedure TForm1.Button5Click(Sender: TObject); var i,j:integer; byte1,byte2,byte3:byte; begin button5.Enabled:=false; memo1.Enabled:=false; button5.Caption:='Removing empty Data'; for i:=0 to memo1.Lines.Count do begin memo1.Lines[i]:=stringreplace(memo1.Lines[i],' ','',[rfReplaceAll]); memo1.Lines[i]:=stringreplace(memo1.Lines[i],#13+#10,'',[rfReplaceAll]); if memo1.Lines.ValueFromIndex[i]='' then memo1.Lines.Delete(i);end; button5.Caption:='Removing dublicates'; for i:=0 to memo1.Lines.Count do begin for j:=0 to memo1.Lines.Count do if (memo1.Lines[i]=memo1.Lines[j]) AND (i<>j) then memo1.Lines.Delete(j); end; button5.Caption:='Scanning'; byte1:=00; byte2:=02; byte3:=32; progressbar1.Max:=memo1.Lines.Count; for i:=0 to memo1.Lines.Count do begin udpsockutil1.RemoteHost:=stringreplace(memo1.Lines[i],#13+#10,'',[rfReplaceAll]); if udpsockutil1.RemoteHost='255.255.255.255' then memo1.Lines.Delete(i) else udpsockutil1.SendText(chr(byte2)+chr(byte1)+chr(byte1)+chr(byte3)+chr(byte1)+chr(byte1)+chr(byte1)+chr(byte1)+chr(byte1)); progressbar1.Position:=i; end; button5.Caption:='Scan for Games'; button5.Enabled:=true; memo1.Enabled:=true; progressbar1.Position:=0; end; |
Delphi-Quelltext
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:
| procedure TForm1.UdpSockUtil1Receive(Sender: TObject); var Len: Integer; servername,gamemode,levelname,s,ip: String; vonIP: in_addr; i,currentlyplaying,maxplayers:integer; newserver:TTreenode; begin Len := UdpSockUtil1.ReceiveLength; if Len =166 then begin servername:=''; gamemode:=''; levelname:=''; s:=udpSockUtil1.ReceiveText(vonIP); ip:=string(inet_ntoa(vonIP)); ips.Add(ip); for I:=62 to 93 do servername:=servername+s[i]; for I:=94 to 125 do gamemode:=gamemode+s[i]; for I:=126 to 157 do levelname:=levelname+s[i]; currentlyplaying:=ord(s[158]); maxplayers:=ord(s[162]); newserver:=treeview1.Items.add(nil,ip+': '+servername); treeview1.items.AddChild(newserver,'Gamemode: '+gamemode); treeview1.items.AddChild(newserver,'Level: '+levelname); treeview1.items.AddChild(newserver,'Players: '+inttostr(currentlyplaying)+'/'+inttostr(maxplayers)); ping1.Hostname:=ip; ping1.ResetStatistics; ping1.action; pinging:=true; while pinging do application.ProcessMessages; treeview1.items.AddChild(newserver,'Ping: '+inttostr(lastping)+'ms'); end; |
Config von UDPSockutil1:
Broadcast=false
CloseInactive=false
LocalPort=51762
RemotePort=19400
Wie gesagt, wär echt klasse, wenn mir jemand helfen könnte...
PS: Das Scannen dauert mit dem zweiten Mal höchstens nur noch eine Sekunde, ab dem dritten Mal weniger als eine Sekunde, am Anfang dauerte es aber 2-3 Sekunden...
Narses - So 17.09.06 10:54
Moin!
Force hat folgendes geschrieben: |
Hier ist der Quelltext, wär super, wenn jemand mir helfen könnte.... |
Hm, wenn du deinen Quelltext brauchbar formatierst (
STYLEGUIDE) und aussagekräftige Kommentare einfügst, dann würde ich mir das mal ansehen; aber so ist mir das zu konfus. ;)
Force hat folgendes geschrieben: |
alle Server in einer Liste |
Ein Beispiel für diese Liste wäre dann noch ganz nett. ;)
Force hat folgendes geschrieben: |
Ab dem zweiten Aufruf sendet UDPSOckutil (so weit ich weiß) alle Anfragen nur an einen Server und empfängt nichts mehr (auch wenn die Anfragen an den richtigen Server gesendet wurden). |
Wie bist du auf diese Diagnose gekommen?
Force hat folgendes geschrieben: |
PS: Das Scannen dauert mit dem zweiten Mal höchstens nur noch eine Sekunde, ab dem dritten Mal weniger als eine Sekunde, am Anfang dauerte es aber 2-3 Sekunden... |
Das ist nicht sehr ungewöhnlich und könnte damit zusammenhängen, dass die DNS-Auflösung jetzt aus dem Cache bedient wird, wenn du mit Hostnamen arbeitest. Näheres kann ich erst sagen, wenn du mehr aus dem Kontext deines Projekts vorstellst.
cu
Narses
Force - So 17.09.06 12:13
Zu dem Quelltext:
Delphi-Quelltext
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:
| procedure TForm1.Button5Click(Sender: TObject); var i,j:integer; byte1,byte2,byte3:byte; begin button5.Enabled:=false; memo1.Enabled:=false; button5.Caption:='Removing empty Data'; for i:=0 to memo1.Lines.Count do begin memo1.Lines[i]:=stringreplace(memo1.Lines[i],' ','',[rfReplaceAll]); memo1.Lines[i]:=stringreplace(memo1.Lines[i],#13+#10,'',[rfReplaceAll]); if memo1.Lines.ValueFromIndex[i]='' then memo1.Lines.Delete(i);end; button5.Caption:='Removing dublicates'; for i:=0 to memo1.Lines.Count do begin for j:=0 to memo1.Lines.Count do if (memo1.Lines[i]=memo1.Lines[j]) AND (i<>j) then memo1.Lines.Delete(j); end; button5.Caption:='Scanning'; byte1:=00; byte2:=02; byte3:=32; progressbar1.Max:=memo1.Lines.Count; for i:=0 to memo1.Lines.Count do begin udpsockutil1.RemoteHost:=stringreplace(memo1.Lines[i],#13+#10,'',[rfReplaceAll]); if udpsockutil1.RemoteHost='255.255.255.255' then memo1.Lines.Delete(i) else udpsockutil1.SendText(chr(byte2)+chr(byte1)+chr(byte1)+chr(byte3)+chr(byte1)+chr(byte1)+chr(byte1)+chr(byte1)+chr(byte1)); progressbar1.Position:=i; end; button5.Caption:='Scan for Games'; button5.Enabled:=true; memo1.Enabled:=true; progressbar1.Position:=0; end; |
Delphi-Quelltext
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:
| procedure TForm1.UdpSockUtil1Receive(Sender: TObject); var Len: Integer; servername,gamemode,levelname,s,ip: String; vonIP: in_addr; i,currentlyplaying,maxplayers:integer; newserver:TTreenode; begin Len := UdpSockUtil1.ReceiveLength; if Len =166 then begin servername:=''; gamemode:=''; levelname:=''; s:=udpSockUtil1.ReceiveText(vonIP); ip:=string(inet_ntoa(vonIP)); ips.Add(ip); for I:=62 to 93 do servername:=servername+s[i]; for I:=94 to 125 do gamemode:=gamemode+s[i]; for I:=126 to 157 do levelname:=levelname+s[i]; currentlyplaying:=ord(s[158]); maxplayers:=ord(s[162]); newserver:=treeview1.Items.add(nil,ip+': '+servername); treeview1.items.AddChild(newserver,'Gamemode: '+gamemode); treeview1.items.AddChild(newserver,'Level: '+levelname); treeview1.items.AddChild(newserver,'Players: '+inttostr(currentlyplaying)+'/'+inttostr(maxplayers)); ping1.Hostname:=ip; ping1.ResetStatistics; ping1.action; pinging:=true; while pinging do application.ProcessMessages; treeview1.items.AddChild(newserver,'Ping: '+inttostr(lastping)+'ms'); end; |
Beispiel für Liste (TMemo):
127.0.0.1
localhost
192.168.0.1
192.168.0.2
(hier stehen normalerweise IPs/DNS' für Server im Internet)
Zitat: |
Wie bist du auf diese Diagnose gekommen? |
Ich hab die gesendeten/empfangen Packete aufgezeichnet ;)
Narses - So 17.09.06 23:11
Moin!
Hm, nennst du das "formatierten Quelltext" und "aussagekräftige Kommentare"... ? :nixweiss: :roll:
Kannst du den Code nicht mal auf die definitiv relevanten Teile kürzen und exakt beschreiben, warum du das tust (was die Befehle machen, kann ich auch sehen...)? Danke. ;)
Was sind das für Server? Hast du die programmiert? Wer hat das Protokoll definiert? Beispiele?
Mir fällt auf Anhieb eigentlich nur folgendes am Code auf, für den Rest blicke ich einfach nicht brauchbar durch, ohne Stunden da rein zu investieren:
Force hat folgendes geschrieben: |
Delphi-Quelltext 1:
| for i:=0 to memo1.Lines.Count-1 do begin | |
Du läufst mit dem Index permanent eins zu weit. ;)
Force hat folgendes geschrieben: |
Beispiel für Liste (TMemo): |
Naja, dadrauf wäre ich dann auch gerade noch selbst gekommen... ;)
Force hat folgendes geschrieben: |
(hier stehen normalerweise IPs/DNS' für Server im Internet) |
Und genau dafür hätte ich gerne mal ein Beispiel gesehen, um das mal selbst zu probieren. :D
Aber zumindest ist jetzt klar, warum das beim erst Aufruf länger dauert, als bei den folgenden; die Hostnamensauflösung kommt aus dem Cache. Gib mal zwischendurch "ipconfig /flushdns" ein, dann dauert das auch wieder länger. ;)
Force hat folgendes geschrieben: |
Zitat: | Wie bist du auf diese Diagnose gekommen? |
Ich hab die gesendeten/empfangen Packete aufgezeichnet ;) |
Womit? Und was genau hast du untersucht?
cu
Narses
Force - Di 19.09.06 15:48
Narses hat folgendes geschrieben: |
Was sind das für Server? Hast du die programmiert? Wer hat das Protokoll definiert? Beispiele? |
Es handelt sich hierbei um Airfix Dogfigher Server (siehe auch:
Hinweise zum ADF-Protokoll [
http://www.jasdeepbansal.co.uk/Misc/Airfix_Dogfighter/]
Narses hat folgendes geschrieben: |
Mir fällt auf Anhieb eigentlich nur folgendes am Code auf, für den Rest blicke ich einfach nicht brauchbar durch, ohne Stunden da rein zu investieren:
Du läufst mit dem Index permanent eins zu weit. ;) |
Stimmt, das hab ich übersehen :D
Narses hat folgendes geschrieben: |
Womit? Und was genau hast du untersucht? |
Mit einem Packetdumper namens WPE Pro Alpha
Narses - Di 19.09.06 22:56
Moin!
Wenn du die Liste aus dem Archiv hast, dann würde ich sagen, da läuft einfach kein entsprechender Server oder der Antwortet nicht auf das MagicPaket.
Hier mein Testprojekt (mit spiegelndem Server, damit man das auch mal real testen kann ;)).
cu
Narses
Force - Mi 20.09.06 12:54
Ich hab zwar viele IPs auch aus dem Archiv, aber es ist auch möglich den Server lokal zu starten.
Trotzdem, wie schon gesagt, beim ersten Mal funktioniert es auch auch ohne Probleme, erst wenn die Procedure das zwetite Mal ausgeführt wird geht es nicht mehr...
Ich werd es mal mit deinen Projekten versuchen, vielen Dank dass du dir so viel Arbeit damit machst :D
testra - Di 26.09.06 09:08
kann man das ganze auch ohne formulare machen, ohne buttons usw.
Wie sähe der code aus, wenn ich nur datenempfang evtl. verschlüsselung vom server habe möchte und das vielleicht nur unter dem DOS-Fenster ausgeben möchte?
Narses - Di 26.09.06 09:31
Moin!
testra hat folgendes geschrieben: |
kann man das ganze auch ohne formulare machen, ohne buttons usw. |
Nein, du brauchst das TApplication-Objekt für den MessageLoop, sonst kannst du die Nachrichten nicht verarbeiten.
cu
Narses
testra - Di 26.09.06 09:35
das gefällt mir nun gar nicht. :shock:
mein programm läuft ohne formulare und berechnet nur etwas, gibt das ergebnis in einer textdatei aus.
Als Sicherheit und Schutz, soll mein programm, damit es laufen soll, vom server einen text erhalten, das verschlüsselt ist, soll es vergleichen und dann somit das program starten.
aber ohne visuelle komponenten.
wie kann ich mit dem server kommunizieren, um diesen text zu erhalten.
die verschlüsselung wäre dann das nächste problem.
Narses - Di 26.09.06 10:32
Moin!
testra hat folgendes geschrieben: |
Als Sicherheit und Schutz, soll mein programm, damit es laufen soll, vom server einen text erhalten, das verschlüsselt ist, soll es vergleichen und dann somit das program starten. |
Ich hoffe doch, dass dein Programm den Benutzer aber darüber informiert, dass es Daten mit deinem Server austauscht... :shock:
testra hat folgendes geschrieben: |
aber ohne visuelle komponenten. |
Das ist ja auch OK, hab ich auch nicht gesagt. ;) Es geht nur um das TApplication-Objekt. ;) Und das auch nur für die Nachrichtenverarbeitung (asynchrone Benachrichtigung). Du kannst auch einen Thread abspalten und mit blocking-socket-calls direkt auf die WSA zugreifen und UDP-Transfers machen. :D
cu
Narses
testra - Di 26.09.06 10:35
ja moin auch!!
ist mir leider ein bischen zu hoch-deutsch!
ich bin da in socket-programmierung nämlich ein anfänger.
ein code-schnipsel wäre mir da lieber.. :roll:
Narses - Di 26.09.06 10:46
Moin!
testra hat folgendes geschrieben: |
ich bin da in socket-programmierung nämlich ein anfänger. |
In diesem Fall würde ich dir dazu raten, eine Formular-Anwendung zu machen und einfach das Fenster zu verstecken. Code gibts dazu hier im Forum genug.
cu
Narses
testra - Di 26.09.06 13:32
ok, vielen dank!
werde ich versuchen.
trotzdem hätte es mich sehr interessiert, wie es ohne die gui funktioniert.. :wink:
Narses - Di 26.09.06 13:47
Moin!
testra hat folgendes geschrieben: |
trotzdem hätte es mich sehr interessiert, wie es ohne die gui funktioniert.. :wink: |
Ich habe dir bereits einen Vorschlag gemacht; dein Kommentar:
testra hat folgendes geschrieben: |
ist mir leider ein bischen zu hoch-deutsch! |
:D
cu
Narses
testra - Mi 27.09.06 12:31
man findet leider viel zu wenig stoff zu socket programmierung, und wenn dann nur mit der gui.
wie soll ich überhaupt das formular verstecken, die ganzen routinen nützen mir doch nix, weil
vieles auf onklick ereignisse aufgebaut ist. ich hätte die server-verbindung + datenempfang
ohne klicks; wie der aublauf in einer datei gesammelt werden soll ist mir noch völlig unklar.
Narses - Mi 27.09.06 13:34
Moin!
testra hat folgendes geschrieben: |
wie der aublauf in einer datei gesammelt werden soll ist mir noch völlig unklar. |
Ich will dir ja nicht zu nahe treten, aber vielleicht solltest du dich erstmal mit den "wichtigen" Problemen beschäftigen und dann erst dafür sorgen, dass das ganze ohne GUI läuft. Wenn du das schon mit einer GUI nicht hinkriegst, dann wird das ohne GUI schonmal gar nix, oder? :D
testra hat folgendes geschrieben: |
wie soll ich überhaupt das formular verstecken, die ganzen routinen nützen mir doch nix, weil vieles auf onklick ereignisse aufgebaut ist. ich hätte die server-verbindung + datenempfang ohne klicks; |
Grundsätzlich: wer hat denn gesagt, dass für den Datenempfang ein OnClick-Ereignis nötig ist? :gruebel: Dem ist nicht so! ;)
Vorschlag: mach deine Anwendung doch erstmal mit einem normalen Fenster und einem Button, in dessen Handler du alles "Nötige" zum Senden abwickelst.
Wenn das einwandfrei klappt, dann verschiebst du die Aktionen aus dem ButtonHandler in das FormCreate und setzt da auch als erstes den Code zum Fenster-verstecken ein.
Im Receive-Event behandelst du dann, was vom Server zurück kommt und beendest ggfs. die Anwendung. Und dabei wird kein Fenster je des Benutzers Auge streifen... ;)
cu
Narses
wurzel - Fr 15.12.06 09:19
Titel: Help
Ich kann die Komponente nicht in mein Delphi 2006 reinklöppeln, die will einfach net. Den Punkt "Komponente installieren" gibts bei mir nicht, nur "Neue VCl-Komponente", "Packages installieren" und "Komponente importieren". So, nun denke ich mir, dass ich mal "Neue VCL-Komponente" anklicke, da kann ich aber keine neuen Komponenten hinzufügen. Bitte, helft mir ^^
wulfskin - Fr 15.12.06 10:38
Titel: Re: Help
wurzel hat folgendes geschrieben: |
Ich kann die Komponente nicht in mein Delphi 2006 reinklöppeln, die will einfach net. Den Punkt "Komponente installieren" gibts bei mir nicht, nur "Neue VCl-Komponente", "Packages installieren" und "Komponente importieren". So, nun denke ich mir, dass ich mal "Neue VCL-Komponente" anklicke, da kann ich aber keine neuen Komponenten hinzufügen. Bitte, helft mir ^^ |
Hallo,
erstell ein Package oder, weil du wahrscheinlich nicht weißt wie das geht, lass es Narses für dich machen! ;) Das gehört sowieso eigentlich immer dazu!
Gruß Hape!
wurzel - Fr 15.12.06 10:59
Joa, wenn es einer machen könnte, wäre es cool, oder du sagst mir schnell, wie ich ein Package mache, oder wo ich ein Tut finde
wurzel - Fr 15.12.06 11:07
Muhaha, ich habe Feuer gemacht ^^. Ich habe es ehr wohl alleine hingekriegt, einfach "Datei - Neu - Weitere - Package". Dann mit Rechtsklick auf das Package im Projektmanager, "Hinzufügen" auswählen und die *.pas raussuchen. Und dann nur noch installieren. Fertig ^^.
hui1991 - Sa 23.12.06 11:03
Hi,
so nach langer Zeit versuche ich es mit D7 nochmal. Die komponente wird irgendwie in Internet eingefügt.
Ich hoffe das jetzt die anderen das besser installieren können.
Hätte wurzel nicht gesagt wie, dann hätte ich es aufgegeben.
Da ich schon vergessen hab wie man das installiert ^^
Jetzt wird erstmal getestet ^^
MfG
hui1991
Edit:// Okay es installiert doch nicht :(
xZise - Di 28.08.07 07:18
Entschuldigung, dass ich Thread so ausgrabe, aber ich benötige die Unit für Delphi 5, da ich hier nichts anderes habe.
Nun. Die Ressourcestrings konnte ich einbauen, und das verletzten der Grenzen auch (durch casten), aber jetzt meint er:
Quelltext
1: 2: 3: 4: 5: 6: 7:
| [Fehler] UdpSockUtil.pas(262): Undefinierter Bezeichner: 'DeallocateHWnd' [Fehler] UdpSockUtil.pas(300): Undefinierter Bezeichner: 'AllocateHWnd' [Fehler] UdpSockUtil.pas(300): Nicht genügend wirkliche Parameter [Warnung] UdpSockUtil.pas(372): Konstantenausdruck verletzt untere Grenzen [Warnung] UdpSockUtil.pas(386): Der Vergleich ergibt immer Falsch [Warnung] UdpSockUtil.pas(405): Der Vergleich ergibt immer Falsch [Warnung] UdpSockUtil.pas(495): Konstantenausdruck verletzt untere Grenzen |
Crosspost mit der DP [
http://www.delphipraxis.net/post768782.html#768782]
Narses - Di 28.08.07 09:09
Moin!
xZise hat folgendes geschrieben: |
ich benötige die Unit für Delphi 5, da ich hier nichts anderes habe. |
An dieser Stelle waren wir leider schonmal (s.o.). Wenn du allerdings nur D5 hast, ist hier Ende, weil ich kein D5 habe und dir leider nicht weiterhelfen kann. :nixweiss: :(
cu
Narses
barrais - Di 02.10.07 09:53
du hast gestern gemeint, wenn man die Unit-Referenzen anpasst, lässt sich TUdpSockUtil mit D5 compilieren.
Weißt du vielleicht welche das sind? und wie man die anpassen kann?
Narses - Di 02.10.07 11:07
Moin!
phlux in der DP hat folgendes geschrieben: |
ein bisschen google hätte geholfen, für
Zitat: | [Fehler] UdpSockUtil.pas(262): Undefinierter Bezeichner: 'DeallocateHWnd'
[Fehler] UdpSockUtil.pas(300): Undefinierter Bezeichner: 'AllocateHWnd' |
musst du die unit classes einbinden ab delphi 6, delphi5 und kleiner die unit forms.
der letzte fehler hängt damit zusammen, dass du zu wenige parameter übergibst |
Also einfach mal:
ergänzen und sehen, was der Compiler sagt. :nixweiss:
Ich habe leider kein D5, deshalb kann ich dir nicht wirklich helfen... :|
cu
Narses
barrais - Di 02.10.07 12:30
Danke Narses, es hat funktioniert!
Keine Fehler mehr, nur Warnungen:
[Warnung] UdpSockUtil.pas(230): Konstantenausdruck verletzt untere Grenzen
bezieht sich auf folgende Zeile: (FRemoteAddr.S_addr := INADDR_BROADCAST;)
[Warnung] UdpSockUtil.pas(387): Der Vergleich ergibt immer Falsch
bezieht sich auf folgende Zeile: if (Value.S_addr = INADDR_BROADCAST) then
[Warnung] UdpSockUtil.pas(387): Vorzeichenbehaftete und -lose Typen werden verglichen - beide Operanden werden erweitert
bezieht sich auf folgende Zeile: if (Value.S_addr = INADDR_BROADCAST) then
was meinst du, ist das was ernsthaftes, oder kann ich die ignorieren?
Narses - Di 02.10.07 12:57
Moin!
Mach das mal so:
Delphi-Quelltext
1: 2: 3: 4: 5:
| FRemoteAddr.S_addr := Integer(INADDR_BROADCAST);
if (Value.S_addr = Integer(INADDR_BROADCAST)) then
if (Value.S_addr = Integer(INADDR_BROADCAST)) then |
Was sagt der Compiler jetzt?
cu
Narses
barrais - Di 02.10.07 13:38
Danke schön!
der Compiler mekert nicht mehr!
ich versuche jetzt ein binäres Protokoll mit TUdpSockUtil zu schreiben.
Könntest du mir vieleicht Tipps geben?(ich weiß, ich frage zuviel, sorry..)
Narses - Di 02.10.07 14:14
Moin!
barrais hat folgendes geschrieben: |
Danke schön!
der Compiler mekert nicht mehr! |
Fein; bitte. ;) Schickst du mir mal die pas-Datei der Unit per PN zu, damit ich die Änderungen für D5 in das Projekt einpflegen kann?
barrais hat folgendes geschrieben: |
ich versuche jetzt ein binäres Protokoll mit TUdpSockUtil zu schreiben.
Könntest du mir vieleicht Tipps geben?(ich weiß, ich frage zuviel, sorry..) |
Grundsätzlich, ja. Aber da ich keine Ahnung habe, was das Ziel dieser Aktion sein soll und welche Daten verarbeitet werden, weiß ich nicht, wie. :nixweiss:
cu
Narses
barrais - Di 02.10.07 14:48
Hi,
die .pas-Datei habe ich dir per PN geschickt.
Was mein Projekt angeht:
ich habe vor, ein Anwendungsprogramm mit Delphi zu schreiben, das ein Mikrocontroller steuert; und zwar das Programm schickt per Ethernet UDP-Pakete zu dem Mikrocontroller, die Pakete enthalten Kommandos ( Start, Stop, Capture,...), der Mikrocontroller(werde ich noch mit C programmieren) reagiert dem Kommando entsprechend(z.B. start: Messung starten, stop: Messung stoppen, capture: die Messdaten zum PC schicken).Es geht um CAN-Bus Daten (also Binäre daten), die das Anwendungsprogramm dann speichert und binär(halt so wie sie sind!) darstellen muss.
Ich hoffe, du hast jetzt einen Überblick über das projekt.
ich bin für jeden Tipp Dankbar!
barrais - Do 04.10.07 08:34
Danke für Deine Tipps
Ernst Budde - Di 30.10.07 13:21
Titel: TUDPSockUtil für Delphi5
Ich habe jetzt TUDPSockUtil für Delphi 5 (Windows 2000) installiert. Dazu musste ich RTLConsts.pas hinzufügen und die beiden Classes. .. Aufrufe durch Forms. .. ersetzen.
Kompilieren geht jetzt gut. Aber der erste Test scheitert:
Ich starte z.B. UdpLanChat.exe aus dem Tutorial zweimal auf meinem Rechner. Der 'Senden' Button ist dann zunächst bei beiden grau.
Bei einer der beiden Anwendungen kann ich jetzt 'Online' drücken: Der Senden Button wird dann aktiv. Sobald ich aber auf der anderen Anwendung 'Online' drücke, bekomme ich ERROR 10048 und der 'Senden' button bleibt grau. Es kann doch nicht sein, dass man nur sich selbst etwas senden kann!
Ich habe den Code der Komponente noch nicht gelesen (und möchte das eigentlich auch nicht), aber eine Frage: Wird vielleicht beim Drücken des 'Online' Button versucht, einen SERVER einzurichten? Das sollte ja bei UDP nicht nötig sein, würde aber den Fehler erklären, denn auf einem Rechner dürfen nicht zwei Server mit gleicher Portnummer arbeiten.
Ernst
Narses - Di 30.10.07 14:38
Titel: Re: TUDPSockUtil für Delphi5
Moin!
Ernst Budde hat folgendes geschrieben: |
eine Frage: Wird vielleicht beim Drücken des 'Online' Button versucht, einen SERVER einzurichten? |
Genau so ist es. ;)
Ernst Budde hat folgendes geschrieben: |
Das sollte ja bei UDP nicht nötig sein, |
Aha, und wie willst du dann Daten empfangen? :gruebel:
Ernst Budde hat folgendes geschrieben: |
würde aber den Fehler erklären, denn auf einem Rechner dürfen nicht zwei Server mit gleicher Portnummer arbeiten. |
AFAIR steht genau zu deinem "Problem" ein entsprechender Hinweis im Chat-Tut. ;) Man kann das Demo-Programm jeweils nur einmal auf dem PC online schalten.
cu
Narses
GrubenPete - Mo 17.03.08 00:43
Hi, ich benutze TUdpSockUtil um im LAN alle aktiven Server für mein Spiel zu finden.
Gleichzeitig läuft auch ein TCPServer (von den Indys).
UDPSockUtil.Listen hab ich auf true und der TCPServer is auch aktiv.
Sende ich nun ne Broadcast erhalte ich ganz normal Antworten von allen Servern, will ich mich aber dann mit einem von denen per TCP Verbinden, kommt ein 'Connection refused'.
Hab dann mal testweise vorm verbinden mit TCP über die UDP-Komponente an meinen RemoteHost nen Befehl gesendet, der Listen auf false setzt und siehe da, ich kann mich via TCP auf den Host verbinden.
Nun meine Frage.^^ Lässt sich das irgendwie unterbinden, dass ich den UDP-'Listener' ausschalten muss, um mich mit dem TCPServer zu vebinden ?
Sascha
Narses - Mo 17.03.08 01:00
Moin!
GrubenPete hat folgendes geschrieben: |
Hab dann mal testweise vorm verbinden mit TCP über die UDP-Komponente an meinen RemoteHost nen Befehl gesendet, der Listen auf false setzt und siehe da, ich kann mich via TCP auf den Host verbinden.
Nun meine Frage.^^ Lässt sich das irgendwie unterbinden, dass ich den UDP-'Listener' ausschalten muss, um mich mit dem TCPServer zu vebinden ? |
TCP und UDP haben je einen eigenen Port-Adressraum, ausserdem wird ja für den TCP- und den UDP-Listener je ein eigenes Binding erstellt. Ich kann mir nicht vorstellen, dass der
TUdpSockUtil den
IdTCPServer daran hindern sollte, eine Verbindung anzunehmen. :nixweiss:
Kurz: ich kann dir nicht sagen, woran es in deinem Projekt liegt, aber deinen "Verdacht" halte ich für sehr unwahrscheinlich. :gruebel: (ich habe selbst Projekte in dieser Konstellation laufen, da gibt es keine Probleme)
cu
Narses
GrubenPete - Mo 17.03.08 12:17
Hmm, hatte ich mir ja eigentl. auch gedacht, aber hab trotzdem mal verschiedene Ports ausprobiert. Ohne Erfolg.
Aus irgendeinem Grund müssen sich die beiden Server aber irgendwie in die Quere kommen, ich weiß aber nich warum.
Wenn ich wieder ab meinem PC bin poste ich mal den relevanten Quellcode sowie die einzelnen Einstellungen... Vielleicht findet sich ja dann irgendwo ein Fehler^^
Sascha
GrubenPete - Mo 17.03.08 15:54
Joa, das sind die meiner Meinung nach relevanten Zeilen..
Unit1
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:
| [...]
procedure TForm1.FormCreate(Sender: TObject); begin myUDP := TUDPSockUtil.Create(self); myUDP.RemotePort := UDP_PORT; myUDP.LocalPort := UDP_PORT; myUDP.OnReceive := myUDPReceive; myUDP.OnError := myUDPError; myUDP.Listen := true;
myTCPClient.BoundIP := myIPWatch.LocalIP; myTCPClient.BoundPort := TCP_CLIENT_PORT; myTCPServer.DefaultPort := TCP_SERVER_PORT; myTCPServer.Active := true;
[...]
end;
procedure TForm1.Button2Click(Sender: TObject); begin Log.Lines.Add(TimeToStr(now) +': Sending Broadcast Question'); myUDP.BroadcastText(APP_ID+#13+ Syntax[cmdBroadAsk].Text+#13); ServerList.SetFocus; end;
procedure TForm1.ServerListClick(Sender: TObject); var server: string; begin if ( ServerList.Row > 0 ) and ( ServerList.Row < ServerList.RowCount ) and not ( ServerList.Cells[1,ServerList.Row] = '' ) then begin server := copy(ServerList.Cells[1,ServerList.Row],1,pos(' (',ServerList.Cells[1,ServerList.Row])); Log.Lines.Add('Trying to connect to ' + server); myUDP.RemoteHost := server; myUDP.SendText(APP_ID+#13+ Syntax[cmdStop].Text+#13); myTCPClient.Host := server; myTCPClient.Port := TCP_SERVER_PORT; myTcpClient.Connect(); end; end;
[...] |
Narses - Mo 17.03.08 16:26
Moin!
Der Codeschnipsel ist zu kurz, da kann ich nix erkennen. Interessanter ist auch eher die Empfänger-Seite, würde ich sagen. Vor allem ist der IdTCPServer ja multithreaded; sicher, dass du dir da keine Thread-Problematik eingehandelt hast? Wäre jetzt so mein Tipp... :nixweiss:
cu
Narses
GrubenPete - Mo 17.03.08 17:20
Hey, es lag an den Threads^^ Sorry, aber is das erste mal, dass ich so richtig mit den Indys arbeite.
Das Verbinden klappt jetzt wunderbar, jedenfalls beim ersten mal.
Danke trotzdem^^
Sascha
Jann1k - Mo 17.03.08 23:18
Hi Narses,
ich versuche grade die Komponente zu installieren und halte mich dabei an dein Tutorial. Mein delphi 7 gibt mir auch die Meldung aus dass das Projekt neu kompiliert werden muss, klicke ich dann auf "Ja" kriege ich folgende Fehlermeldung :
Delphi-Quelltext
1:
| [Fatal Error] dclusr.dpk(47): File not found: 'GIFCODE.dcu' |
und das installieren der Komponente scheitert.
Zusätzlich kriege ich noch zwei Warnungen:
Delphi-Quelltext
1: 2: 3:
| [Warning] dclusr.dpk(5): File not found: '..\..\..\..\dokumente und einstellungen\sebastian & martin\desktop\icq_20040630\icq\component\ICQClient.dcr'
[Warning] dclusr.dpk(6): File not found: '..\..\..\..\Dokumente und Einstellungen\Sebastian & Martin\Desktop\icq_20040630\ICQ\Component\ICQDb.dcr' |
Was tun?
Narses - Mo 17.03.08 23:33
Moin!
Jann1k hat folgendes geschrieben: |
klicke ich dann auf "Ja" kriege ich folgende Fehlermeldung :
Quelltext 1:
| [Fatal Error] dclusr.dpk(47): File not found: 'GIFCODE.dcu' |
und das installieren der Komponente scheitert.
Zusätzlich kriege ich noch zwei Warnungen: |
Sieht aus, als wäre dein DefaultUserPackage zermatscht (du wirst vermutlich schon einige andere Komponenten hineininstalliert haben und diese möglicherweise nicht sauber deinstalliert oder Teile der Quellen verschoben). :nixweiss:
Jann1k hat folgendes geschrieben: |
Was tun? |
Du kannst die Komponente einfach in ein neues Package installieren oder das Default-Package (dcluser.dpk) löschen und ein Neues anlegen (wenn du sicher bist, dort keine Kompos drin zu haben, die du aktuell noch im Einsatz hast). :idea:
cu
Narses
Jann1k - Mo 17.03.08 23:45
Zitat: |
Sieht aus, als wäre dein DefaultUserPackage zermatscht |
Gut zu wissen, worauf man beim nöchsten mal achten muss.
Zitat: |
Du kannst die Komponente einfach in ein neues Package installieren oder das Default-Package (dcluser.dpk) löschen und ein Neues anlegen |
Dankeschön, für die schnelle Hilfe - funktioniert problemlos.
Moderiert von Narses: Delphi- durch Quote-Tags ersetzt
aenogym - Mi 09.04.08 21:24
Hi Narses,
erst einmal: vielen Dank für diese super Komponenten!
Jedoch habe ich ein sehr komisches Problem. Sämtliche per SendText() verschickte Nachrichten kommen doppelt bis vierfach an! Und wenn ich einen String sende, der länger als die maximale Datagrammgröße ist, dann wird jedes der aufgesplitteten Einzeldatagramme ebenfalls mehrmals gesendet!
Dieser Effekt tritt komischerweise nur bei meinem privaten PC auf (Delphi 7). Auf meinem Arbeitsrechner (Delphi 6) wird nichts doppelt versendet.
Kann sich das jemand erklären?
Dankbar,
aeno
Narses - Do 17.04.08 13:01
Moin!
aenogym hat folgendes geschrieben: |
erst einmal: vielen Dank für diese super Komponenten! |
Danke für das Lob. ;)
aenogym hat folgendes geschrieben: |
Und wenn ich einen String sende, der länger als die maximale Datagrammgröße ist, dann wird jedes der aufgesplitteten Einzeldatagramme ebenfalls mehrmals gesendet! |
Das ist klar, es wird ja intern auf mehrere Aufrufe runtergebrochen.
aenogym hat folgendes geschrieben: |
Sämtliche per SendText() verschickte Nachrichten kommen doppelt bis vierfach an! |
Da du keinen Code oder konkretes Beispiel genannt hast, rate ich mal: du sendest Broadcasts und hast mehrere Schnittstellen? Dann ist das Verhalten zunächst mal "normal". Falle: bei einem Unicast an einen Host, dessen Adresse nicht aufgelöst werden kann, wird auf Broadcast umgeschaltet! :idea:
cu
Narses
Knulli - Di 07.10.08 11:10
Hi Narses,
ich glaub ich hab nen Bug gefunden...
Also auf einem Rechner läuft ein Client (mit UDPSockUtil), der im Sekundentakt was an einen Server (mit UDPSockUtil) auf einem anderen Rechner sendet. Weil der Client auch auf kleinere Kommandos des Servers auch reagieren soll, gibts da auch ein OnReceive-Eventhandler.
Wenn der Server aber nicht erreichbar ist, gibts im Client ein OnReceive-Ereignis obwohl niemand was gesendet hat. Und zwar immer unmittelbar nachdem er was gesendet hat.
Wenn ich in OnReceive die ReceivLength abfrage, steht 1 Byte drin, wenn ich aber danach mit ReceiveText das Byte abholen will um nachzusehen, was denn da so interessantes drinsteht, gibts ne Exception, die nicht mal durch Setzen des OnError Events unterdrückt werden kann.
Soll das so sein oder mache ich was falsch?
mfg Knulli
Delphi-Quelltext
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:
| unit Client;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, UdpSockUtil, ExtCtrls;
type TfrmClient = class(TForm) Timer1: TTimer; UdpSockUtil1: TUdpSockUtil; procedure FormCreate(Sender: TObject); procedure Timer1Timer(Sender: TObject); procedure UdpSockUtil1Receive(Sender: TObject); procedure UdpSockUtil1Error(Sender: TObject; Error: Integer); private bLaberSuelz: Boolean; public end;
var frmClient: TfrmClient;
implementation {$R *.dfm}
uses WinSock;
procedure TfrmClient.FormCreate(Sender: TObject); begin bLaberSuelz := false; UDPSockUtil1.LocalPort := 12346; UDPSockUtil1.RemotePort := 12345; UDPSockUtil1.RemoteHost := '192.168.100.100'; UDPSockUtil1.CloseInactiveSockets := true; UDPSockUtil1.Open(); Timer1.Enabled := true; end;
procedure TfrmClient.Timer1Timer(Sender: TObject); var st: String; begin if bLaberSuelz then st := 'Laber' else st := 'Sülz'; bLaberSuelz := Not bLaberSuelz; UDPSockUtil1.SendText(st); end;
procedure TfrmClient.UdpSockUtil1Error(Sender: TObject; Error: Integer); begin end;
procedure TfrmClient.UdpSockUtil1Receive(Sender: TObject); var FromAddr: in_Addr; stCmd: String; Anzahl: Integer; begin try Anzahl := UDPSockUtil1.ReceiveLength(); if Anzahl > 0 then begin stCmd := UDPSockUtil1.ReceiveText(FromAddr);
if stCmd = 'Hier spricht Dein Meister' then UDPSockUtil1.SendText('Ja, Chef...'); end;
except Windows.Beep(1000, 10); end; end;
end. |
vladi4k - Di 07.10.08 11:40
Hallo,
ich hatte gleiches Problem wie Knulli
nur anders gelöst:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24:
| function TUdpSockUtil.ReceiveText(var RemoteAddr: in_addr): String; begin SetLength(Result,ReceiveLength); SetLength(Result,ReceiveBuf(Pointer(Result)^,Length(Result),RemoteAddr)); end;
function TUdpSockUtil.ReceiveText(var RemoteAddr: in_addr): String; begin SetLength(Result,ReceiveLength);
if Result<>#0 then SetLength(Result,ReceiveBuf(Pointer(Result)^,Length(Result),RemoteAddr)) else if Assigned(FOnError) then FOnError(Self,WSAECONNRESET) else raise EUSUError.CreateFmt('Zielhost nicht erreichbar!',[]);
end; |
Das Problem war das mein Programm immer abgestürzt hat wenn ich per Timer an ein Host sendete der nicht erreicht war UND in dieser Zeit Fenster von meinem Programm angeklickt habe (z.B. Fenster schieben oder Menü aufklappen). :(
:roll: Vladi
Moderiert von Narses: Code- durch Delphi-Tags ersetzt
Narses - Di 07.10.08 12:19
Moin!
Knulli hat folgendes geschrieben : |
Also auf einem Rechner läuft ein Client (mit UDPSockUtil), der im Sekundentakt was an einen Server (mit UDPSockUtil) auf einem anderen Rechner sendet. Weil der Client auch auf kleinere Kommandos des Servers auch reagieren soll, gibts da auch ein OnReceive-Eventhandler.
Wenn der Server aber nicht erreichbar ist, gibts im Client ein OnReceive-Ereignis obwohl niemand was gesendet hat. Und zwar immer unmittelbar nachdem er was gesendet hat. |
Wird beim Senden jedes mal der Host aufgelöst oder arbeitest du immer mit einer festen IP-Adresse?
Das die WSA was zu einem nicht erreichbaren Host "zu sagen hat", ist erstmal normal. AFAIR wird da ein ICMP-Paket bei Ablehnung und ein internes Ereignis bei Nichterreichbarkeit ausgelöst, inwieweit das in Fensternachrichten (und welche) umgesetzt wird, kann ich aus der Kopf nicht sagen, muss mal in der WSA-Doku wühlen gehen... :lupe: :les:
Knulli hat folgendes geschrieben : |
Wenn ich in OnReceive die ReceivLength abfrage, steht 1 Byte drin, |
Kann mich düster erinnern, dass der IOControl-Call nicht immer exakte Werte liefert (deshalb ja auch die Nachkorrektur beim Lesen), allerdings sollte da nie
mehr als tatsächlich da ist, rauskommen... :? :gruebel:
Ich schau´s mir mal an. ;)
cu
Narses
Knulli - Di 07.10.08 12:44
Hi Narses,
Zitat: |
Wird beim Senden jedes mal der Host aufgelöst oder arbeitest du immer mit einer festen IP-Adresse?
|
ich verwende feste IP Adressen:
Delphi-Quelltext
1:
| UDPSockUtil1.RemoteHost := '192.168.100.100'; |
Sowohl Sender-PC (mehrere) als auch der Empfänger-PC bekommen von mir eine feste IP.
Server = Empfänger: 192.168.100.100
Client = Sender: 192.168.100.101 .. 192.168.100.199
gibt eigentlich schon eine neuere Version als V1.0.0?
mfg Knulli
delphi.crash - Di 31.03.09 21:20
hi,
ich weiß ich bin ein bisschen spät, aber super komponente!
mir stellt sich jetzt die frage, wie kann ich denn die ip eines antwortenden (bei mir) servers im OnReceive-event auflösen?
z.B. habe ich eine listbox und möchte den antwortenden auflisten:
via
Delphi-Quelltext
1: 2:
| server:= UdpUtil1.RemoteAddress; listbox.items.append(server); |
funktioniert das logischerweise ja nicht :)
bin über jede hilfe dankbar,
greetz
delphi.crash - Di 31.03.09 21:30
jetzt wo dus sagst :D
danke
BlumenhunD - Do 21.05.09 19:10
Hallo !
hab deine kompo mal ausprobiert.
bei mir hat sie nur funktioniert wenn ich, selber einen LokalPort festgelegt habe.
ansonstent kommt socket error 10022 ( invalid argument )
Edit: wenn ich mit der kompo arbeite bekomm ich immer ne AccessViolation beim Schließen der Anwendung, egal ob ich bei OnClose .Free FreeAndNil() oder .Close garnix mache
Edit2: ich hab den fehler im Disassembler gefunden: call ntdll.ZwContinue
anscheinend will er vor der finalization noch ne datei aufrufen dei längst freigegeben ist.
Edit3: Der Fehler beim Schließen kommt nur, wenn ich etwas gesendet habe
Narses - Do 21.05.09 21:43
Moin und :welcome: im Forum!
Zeig mal deinen Code, mit deiner Beschreibung kann ich nix anfangen. :nixweiss: Welche Delphi-Version verwendest du?
cu
Narses
API - Fr 22.05.09 00:58
Hallo
Ich habe versucht, die Komponente unter Delphi 2009 zum Laufen zu bringen.
Jedoch werden beim Senden eines Strings zum Teil nicht korrekte Zeichen übertragen.
Ich nehme an, es gibt noch Problemstellen mit Ansi/Unicode.
Folgende Änderungen habe ich gemacht:
Quelltext
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:
| 42c42 < FRemoteHost: String; // dahin senden --- > FRemoteHost: AnsiString; // dahin senden 60c60 < procedure SetRemoteHost(const Value: String); --- > procedure SetRemoteHost(const Value: AnsiString); 90c90 < property RemoteHost: String read FRemoteHost write SetRemoteHost; --- > property RemoteHost: AnsiString read FRemoteHost write SetRemoteHost; 226c226 < FRemoteAddr.S_addr := INADDR_BROADCAST; --- > FRemoteAddr.S_addr := Integer(INADDR_BROADCAST); 369c369 < FRemoteAddr.S_addr := INADDR_BROADCAST; --- > FRemoteAddr.S_addr := Integer(INADDR_BROADCAST); 383c383 < if (Value.S_addr = INADDR_BROADCAST) then --- > if (Value.S_addr = Integer(INADDR_BROADCAST)) then 392c392 < procedure TUdpSockUtil.SetRemoteHost(const Value: String); --- > procedure TUdpSockUtil.SetRemoteHost(const Value: AnsiString); 401,402c401,402 < FRemoteAddr.S_addr := inet_addr(PChar(Value)); // IPdotdot? < if (FRemoteAddr.S_addr = INADDR_NONE) then begin // nein, DNSresolve --- > FRemoteAddr.S_addr := inet_addr(PAnsiChar(AnsiString((Value)))); // IPdotdot? > if (FRemoteAddr.S_addr = Integer(INADDR_NONE)) then begin // nein, DNSresolve 491c491 < ToAddr.sin_addr.S_addr := INADDR_BROADCAST --- > ToAddr.sin_addr.S_addr := Integer(INADDR_BROADCAST) |
API - Sa 23.05.09 06:16
Hat jemand eine Idee, wie ich die Komponente unter D2009 zum Laufen bringe?
Narses - So 24.05.09 22:30
Moin und :welcome: im Forum!
API hat folgendes geschrieben : |
Hat jemand eine Idee, wie ich die Komponente unter D2009 zum Laufen bringe? |
Ich habe kein D2009, deshalb kann ich das nicht testen.
Nimm D7(pro), ist für Win32 eh das beste Delphi. ;)
cu
Narses
API - Di 26.05.09 18:34
Welches das beste Delphi ist 1. subjektiv und 2. kommt drauf an, was man machen möchte resp. muss.
Hat vielleicht sonst jemand eine Idee im DF?
Narses - Di 26.05.09 18:44
Moin!
API hat folgendes geschrieben : |
Welches das beste Delphi ist 1. subjektiv |
Oh, das ist durchaus objektiv betrachtbar :| aber die Diskussion führt zu nichts, das ist wahr. ;)
API hat folgendes geschrieben : |
resp. muss. |
Du wärst der erste, der D2009 nehmen "muss". :?
API hat folgendes geschrieben : |
Hat vielleicht sonst jemand eine Idee im DF? |
Was stört dich an den Indy-Kompos, wenn du den TUdpSockUtil nicht zum Laufen kriegst? :nixweiss:
cu
Narses
Piranha - Mi 01.07.09 18:19
So, jetzt muss ich den Thread auch mal ausgraben.
Ich wollte ganz gerne mal die Broadcasts von UPnP einfangen. Aber irgendwie bekomm ich das nicht auf die Reihe. Mein Router castet von 192.168.1.1 auf 239.255.255.250 Port 1900. Standard halt. Doch was muss ich jetzt bei der UDP Komponente genau machen? Ich hab schon alle möglichen Kombinationen durchprobiert. Local-Port auf 1900, Remote auf 1900 oder Remote auf 1900 und Local auf 0 Remote Addr auf 255.255.255.255 oder auf 239.255.255.250 ... irgendwie kommt da nie was an.
Das da was ankommen müsste lässt sich an WireShark nachweisen.
Zur sicherheit von UPnP bin ich mir im klaren und das muss auch nicht in jedem Post erwähnt werden :D
Btw. Das was ankommt lasse ich einfach in einem Memo ausgeben.
Narses - Fr 03.07.09 10:34
Moin!
Piranha hat folgendes geschrieben : |
Mein Router castet von 192.168.1.1 auf 239.255.255.250 Port 1900. Standard halt. |
Ich weiß noch nicht so genau, was du da machst, aber das oben ist nicht die Broadcastadresse des Netzes 192.168.1.1/8. :nixweiss: Das wäre 192.168.1.255. :idea:
cu
Narses
Piranha - So 05.07.09 17:42
uPnP Broadcastet immer auf 239.255.255.250 Port 1900... das wollte ich halt einfach mitlesen.
Hat sich jetzt eh erledigt, da ich gelesen hab das das Windows schon für mich macht und ich jetzt nurnoch mit der API kämpfen muss.
Narses - Di 23.02.10 21:38
Moin!
Kaum zu glauben aber wahr: ich habe mal die Anpassungen für Unicode-Delphi-Versionen eingebaut. Download im ersten Beitrag, wie immer. ;)
Kann das mal einer unter D2k9 testen? Ich habe nur ein D2010 zum Test hier. :nixweiss:
cu
Narses
Narses - Do 15.03.12 17:39
Moin!
Update auf v2.01, Milestone-Release, unbedingt die Doku ansehen! Details und Download wie immer im ersten Beitrag. ;)
cu
Narses
wdbee - Di 27.11.12 13:14
Hallo Narses,
bin gerade zufällig über diese Komponente gestolpert.
Da ich demnächst etwas in diese Richtung machen wollte, habe ich mir die Komponente herunter geladen und sie mal als Package installiert.
Was daran wichtig ist? Hehe, ich habe Delphi XE3!
Kurz und gut, (wie die Komponente,) nur in der Datei UdpSockUtil in der uses Anweisung "Messages" durch "Winapi.Messages" ersetzt und alles compiliert.
Werde das mal später mit den Demos testen.
Gruß
Wolf-Dieter
revenger - Mi 25.12.13 14:48
Hi,
leider habe ich ein Problem diese Komponente unter Delphi XE4 zu integrieren.
Bekomme beim installieren der Komponente folgende Fehlermeldung:
[dcc32 Fataler Fehler] dclusr.dpk(50): F1026 Datei nicht gefunden: 'C:\Program Files\Embarcadero\RAD Studio\11.0\lib\win32\release\UVersionInfo.dcu
Wäre schön wenn ich dafür eine Lösung finden würde, da ich gerne diese Komponente nutzen möchte.
Gruß und frohe Weihnachten!
Edit:
Ja, neee.. hab nicht darauf geachtet das ich noch andere sachen hinzugefügt hatte bei welchen er den pfad nicht mehr findet!
Alles gut soweit!
OlafSt - Do 26.12.13 00:07
Zur Vervollständigung: Die Komponente funktioniert ausgezeichnet unter XE4 und auch als 64-Bit.
OlafSt - Sa 13.02.16 21:04
Hallo Freunde,
heute hier mal etwas neues. Die UDP-Komponente funktioniert ausgezeichnet auch mit XE7 - das vorab. Aber ich habe hier ein Phänomen, von dem ich nicht so sicher bin, wie das in den Griff zu bekommen ist.
Nehmen wir eine Anwendung, die mehr oder minder regelmäßig via UDP Daten an ein Ziel schickt. Dies ist gar kein großes Problem und funktioniert stundenlang, tagelang, monatelang. Bis der Inhaber des Ziels auf die Idee kommt, seine feste IP gegen eine DynDNS auszutauschen, weil der Provider nun eine alle-24h-Zwangstrennung vornimmt.
Sobald das Ziel also zwangsgetrennt wurde (und sich automatisch via DynDNS wieder bekanntgibt) erreicht meine sendende Anwendung das Ziel nicht mehr. Die IP wird offenbar nur einmal ermittelt (was ich verstehe, ist ja auch aufwändig), durch das neuverbinden verändert sich die Ziel-IP, meine bisherige ist somit ungültig.
Einfache Lösung wäre nun, vom Ziel ein "ACK" zurücksenden zu lassen, doch ist dies eine Fremdanwendung, dieser Weg ist nicht möglich.
Hat jemand eine andere Option ?
jaenicke - Sa 13.02.16 23:54
Wenn du eine feste IP brauchst und sich das nicht anders lösen lässt (Neuverbindung anfordern, ...), bleibt wohl nur auch eine zu benutzen. Dafür könntest du einen virtuellen Server mieten und dort alle Daten 1:1 an deine dynamische Adresse weiterleiten. Das hätte auch den Vorteil, dass du dem Server auch einfach direkt mitteilen kannst, an welche IP er weiterleiten soll, so dass du auch kein DynDNS mehr extern brauchst.
OlafSt - Do 03.03.16 12:53
Eigentlich eine gute Idee, aber vermittel das mal einer Spedition, die keine Ahnung von sowas hat und die durch den eisenharten Wettbewerb jetzt nicht auch noch 2,99/Mon für einen virtuellen Server ausgeben will...
Ich habe mir den Source ein wenig genauer angesehen und kurzerhand ein Flag eingebaut, das die DNS-Auflösung zwangsweise immer wieder neu macht - wenn ich das so möchte. Zwecks Kompatibilität ist dieses Flag immer false, bestehender Code muß also nicht angepaßt werden.
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19:
| TUdpSockUtil = class(TComponent) private [...]
FRemoteHost: AnsiString; FRemoteAddr: in_addr; FRemotePort: Word; FForceResolve: boolean; [...] public constructor Create(AOwner: TComponent); override; destructor Destroy; override; [...] property RemoteAddr: in_addr read GetRemoteAddr write SetRemoteAddr; property RecvFlags: Integer read FRecvFlags write FRecvFlags; property SendFlags: Integer read FSendFlags write FSendFlags; property ForceResolve: boolean read FForceResolve write FForceResolve; [...] end; |
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| constructor TUdpSockUtil.Create(AOwner: TComponent); begin inherited Create(AOwner); Startup; [...] FRemotePort := 0; FCloseInactiveSockets := FALSE; FForceResolve:=false; [...] end; |
Im wesentlichen habe ich die Entscheidung "wir haben den Hostnamen schon gesetzt" umgebaut: Alles bleibt beim alten, es sei denn, wir sind durch das Flag gezwungen.
Delphi-Quelltext
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:
| procedure TUdpSockUtil.SetRemoteHost(const Value: AnsiString); var IP: in_addr; HostInfo: PHostEnt; ErrorCode: Integer; begin if (not FForceResolve) then if (FRemoteHost = Value) then exit;
IP.S_addr := inet_addr(PAnsiChar(Value)); if (IP.S_addr <> Integer(INADDR_NONE)) or (Value = '255.255.255.255') then begin if (CheckAddr(IP)) then begin FRemoteHost := Value; FRemoteAddr := IP; end; end else begin if (Value <> '') then HostInfo := WinSock.GetHostByName(PAnsiChar(Value)) else HostInfo := WinSock.GetHostByName(NIL); if Assigned(HostInfo) then begin IP := PInAddr(HostInfo^.h_addr_list^)^; if (CheckAddr(IP)) then begin FRemoteHost := Value; FRemoteAddr := IP; end; end else begin ErrorCode := WSAGetLastError; if Assigned(FOnResolveError) then FOnResolveError(Self, ErrorCode) else raise EUSUError.CreateResFmt(PResStringRec(@sWindowsSocketError), [SysErrorMessage(ErrorCode), ErrorCode, 'GetHostByName']); end; end; end; |
Anschließend braucht es noch zwei weitere Ansatzpunkte: Das eigentliche Senden. Sowohl SendText als auch SendBuf setzen einfach den RemoteHost-Namen neu, wenn das Force-Flag gesetzt ist - was dann automatisch zur Neuauflösung führt.
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
| function TUdpSockUtil.SendBuf(var Buf; BufSize: Integer): Integer; begin FSocketLock.Enter; try if (FForceResolve) then RemoteHost:=FRemoteHost; CreateBinding(FMainSocket, FLocalPort, FBroadcast); Result := InternalSendBuf(FMainSocket, Buf, BufSize, FSendFlags); finally CleanupSocket(FMainSocket); FSocketLock.Leave; end; end; |
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7:
| function TUdpSockUtil.SendText(const S: AnsiString): Integer; begin if (FForceResolve) then RemoteHost:=FRemoteHost; Result := InternalSendText(FMainSocket, FLocalPort, FBroadcast, S); end; |
Bisherige Tests haben gezeigt, das es keinen ernsthaften Unterschied in der Laufzeit gibt und auch die Stabilität der UDP-Routinen an sich ist nicht betroffen - muß also gut gearbeitet haben.
Schwedenbitter - Mi 14.09.16 11:18
Ich muss dieses Thema mal aufwärmen:
Ich würde gern basierend auf TUdpSockUtil einen Chat-Programmieren. Das ist mit der
Anleitung von Narses [
https://www.entwickler-ecke.de/viewtopic.php?t=56272] eigentlich vergleichsweise einfach. Ich habe aber den Eindruck, dass mir Windows 10 gewaltig dazwischen funkt. So klappt schon der Beispielchat nicht unter Windows 10 - keine Fehlermeldungen, Exceptions oder dergleichen. Wenn ich einen oder mehrere Clients in einer VM (Windows XP) laufen lasse, klappt alles prima.
Interessant ist, dass die Clients unter Windows 10 die UDP-Pakete des XP-Clients
empfangen können. Senden sie aber Pakete, scheint Windows 10 diese abzufangen. Sie gelangen also nicht mehr zu den XP-Clients. Bzgl. der Firewall wird man gleich nach dem Online-Gehen von Windows gefragt, ob das Programm im Netzwerk "funken" darf. Selbst das vollständige Abschalten der Windows-Firewall bringt nichts.
Ich habe schon zum Thema UDP und Windows 10 die Suchmaschinen bemüht. Aber eine Lösung oder einen Ansatz dazu habe ich leider nicht gefunden. Ich bin also ziemlich ratlos.
Hat jemand Ideen? Wo kann man dazu Näheres finden?
Gruß, Alex
jaenicke - Mi 14.09.16 12:31
Das Beispiel hatte bei mir unter Windows 10 abgesehen von den Multi-Screen Bugs (weil es in Delphi 7 kompiliert ist, ist das Fenster beim Starten außerhalb des Bildschirmbereichs) problemlos funktioniert.
Schwedenbitter - Do 15.09.16 07:07
jaenicke hat folgendes geschrieben : |
Das Beispiel hatte bei mir unter Windows 10 abgesehen von den Multi-Screen Bugs (weil es in Delphi 7 kompiliert ist, ist das Fenster beim Starten außerhalb des Bildschirmbereichs) problemlos funktioniert. |
Könntest Du mir bitte mal sagen, welches Windows 10 (also Professional/Home etc.)?
Wir haben hier 11 Rechner mit Windows 10 (alle Professional). 8 von denen noch mit Built 10586 und 3 mit 14393.
Ich habe dann gestern nochmal auf virtuellen Maschinen (XP, 7) und echten getestet. Überall läuft es prima, bloß unter den 10ern nicht.
Ich weiß, dass ist OT und aufgrund meiner Tests gehe ich davon aus, dass es ausnahmslos an Windows 10 liegt. Ich versuche bloß zu verstehen, warum das bei Deinem Windows 10 klappt und hier mit 11 Systemem nicht. Das ist merkwürdig.
jaenicke - Do 15.09.16 07:23
Das ist ebenfalls Windows 10 Professional.
Ist das Netzwerk bei euch als privates Netzwerk markiert? Vielleicht steht das auf öffentlich, wo dann standardmäßig stärker abgeschirmt wird.
Schwedenbitter - Do 22.09.16 16:12
Ich habe das Problem gefunden. Entschuldigt, dass ich die Pferde scheu gemacht habe und danke für Eure Hilfsbereitschaft!
Das Problem war/ist VirtualBox. Es legt einen virtuellen Netzerk-Adapter an mit einem anderen Subnetz (z.B. 192.168.56 statt 192.168.178). TUdpSockUtil nutzt nun diesen Adapter, womit die UDP-Pakete nicht mehr ankommen. Wenn ich jetzt von Hand die IP-Adresse des jeweiligen Adapters beim property BindTo eintrage, klappt es.
Allerdings hatte ich die ausführliche pdf-Datei zu TUdpSockUtil so verstanden, dass es hätte trotzdem klappen sollen/müssen, wenn man Brodcast := True setzt. Das tut es merkwürdiger Weise aber nicht.
Das Problem bringt mich zu einer weiteren Frage:
Wir haben 2 Standorte mittels 2 FritzBoxen via VPN verbunden. Diese haben daher notwendiger Weise ebenfalls 2 verschiedene Subnetze. Gäbe es dafür eine Lösung oder kann ich UDP gleich ad acta legen?
Ich hätte sonst erstmal versucht, ob die FritzBoxen überhaupt UDP-Pakete durchleiten.
Schwedenbitter - Mo 10.10.16 17:54
Ich muss leider nochmal pushen.
Ich komme mit unseren über VPN verbundenen Netzen nicht weiter. Es handelt sich dabei um zwei Subnetze mit 192.168.x.0. Innerhalb des nahen Subnetzes tut es ein Broadcast auf 192.168.x.255 bei der Maske 255.255.255.0. Leider komme ich möglicher Weise an den Routern nicht vorbei. Laut AVM wird innerhalb des VPN nichts geblockt. Damit müsste eigentlich ein Broadcast an 255.255.255.255 auch auf dem entfernten Subnetz ankommen, tut es aber nicht.
Zur Abhilfe war mein Plan daher, beim An- und Abmelden, statt eines Broadcast an alle möglichen Clients zu senden, die sich aus dem Adressbereich 192.168.x.y ergeben. Das dauert ca. 2 Sekunden, womit ich leben könnte. Es kommt aber nichts an - nicht einmal mehr im hiesigen Netz.
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9:
| For SNet:= 0 To 255 Do Begin For IP:= 1 To 254 Do Begin UDPSocket.RemoteHost:= '192.168.' + IntToStr(SNet) + ' .' + IntToStr(IP); UDPSocket.SendText(SendText); End; End; Application.ProcessMessages; |
Im Quellcode von UdpSockUtil.pas steht in Zeile 472 der Kommentar "// im Broadcast-Mode ist jede Adresse erlaubt, da auch Subnet-Broadcasts gehen". Interessant ist für mich der 2. Teil des Satzes.
Wie geht denn so ein Subnet-Broadcast?
Narses - Mo 10.10.16 21:12
Moin!
Klingt für mich wie ein Verständnisproblem mit IP-Netzen. :nixweiss:
Schwedenbitter hat folgendes geschrieben : |
Ich komme mit unseren über VPN verbundenen Netzen nicht weiter. Es handelt sich dabei um zwei Subnetze mit 192.168.x.0. Innerhalb des nahen Subnetzes tut es ein Broadcast auf 192.168.x.255 bei der Maske 255.255.255.0. Leider komme ich möglicher Weise an den Routern nicht vorbei. Laut AVM wird innerhalb des VPN nichts geblockt. Damit müsste eigentlich ein Broadcast an 255.255.255.255 auch auf dem entfernten Subnetz ankommen, tut es aber nicht. |
Und das ist by-design so, es ist ein anderes Netz, also kann ein UDP-Subnet-Broadcast da nicht ankommen. Nur weil du eine Route definiert hast, wie (gerichtete) Pakete einen Netzübergang machen können, gilt das nicht für Nachrichten an ein Subnetz (=Broadcast). :idea: Üblicherweise filtert man darüber hinaus, selbst wenn das klappen sollte, UDP-Broadcasts an Routern raus, damit geschwätzige Protokolle nicht das Netz "zulabern". ;) (Routen definiert man üblicherweise über WAN-Stecken, die eine andere, meist deutlich schlechtere, Bandbreite haben) Kurz: Broadcasts kommen nur im gleichen Subnetz an (alles, was auf die Subnetmask passt, an die der Socket gebunden ist - deshalb heißt die so).
Um da irgendwas sinnvolles empfehlen zu können, habe ich zu wenig Durchblick, wie die Gegebenheiten bei euch sind und was da genau passieren soll. Da möchte ich lieber keine halbgaren Dunst-Empfehlungen aussprechen, das bringt nix. :?
cu
Narses
Schwedenbitter - Mo 17.10.16 19:58
Danke. OK. Das mit dem Broadcast habe ich verstanden - es geht nicht und ich werde es nicht ändern können.
Allerdings habe ich da eine weitere Frage: offenbar ist ein gerichtetes Senden per UDP möglich. Also das Senden eines UDP-Paketes an eine bekannte IP-Adresse im entfernten Netz. Ich habe das getestet und es klappt:
Delphi-Quelltext
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:
| Procedure TMainForm.UDPSocketReceive(Sender: TObject); Var Data : TStringList; vonIP : in_addr; Current : TCmdToken; I : Integer; S : String; Begin Data:= TStringList.Create; Try Data.Text:= String(UDPSocket.ReceiveText(vonIP)); If (Data.Count > 1) Then Begin If (Data.Strings[0] = APP_ID) Then Begin Current:= GetCmdToken(Data.Strings[1]); If (Data.Count >= Succ(Syntax[Current].ArgCount)) Then Execute(Current, Data, vonIP); End; End Else Begin S:= ''; For I:= 1 To Length(Data.Text) Do S:= S + IntToHex(Byte(Data.Text[I]), 2) + ' '; Loggen('', 'FREMDES PAKET: ' + Trim(S)); End; Finally Data.Free; End; End; |
Wenn ich jetzt auf einem Linux-Rechner
im entfernten Netz ein iperf --port 12345 --udp --num 100 --client 192.168.
1.48 absetze, kommt das in meinem Netz hier an. Es sind zwar keine 1.470 Bytes, die iperf standardmäßig rübersendet, aber es kommt immerhin etwas an (FREMDES PAKET: FF FF FF FF 58 05 1D EE 0D 0A).
iperf bietet aber nicht nur einen Client, sondern auch einen Server an, der auf diesem Port lauschen kann. Wenn ich jetzt mit meinem Delphi-Programm
Delphi-Quelltext
1: 2:
| UDPSocket.RemoteHost:= '192.168.255.35'; UDPSocket.SendText:= 'Blablablubb'; |
sende, kommt nichts an. Ich verstehe es so, dass RemoteHost den Empfänger enthält. Oder sehe ich das falsch?
Schwedenbitter - Mo 17.10.16 20:29
Ich nehme alles zurück! Die Pakete kommen auf dem Linux-Rechner an, wenn man die Firewall deaktiviert. Ich will wirklich nicht pushen. Ich schreibe bloß gleich, damit nicht jemand noch mehr in die falsche Richtung denkt.
Das verwirrt mich jetzt allerdings. Wenn man das Delphi-Programm in der IDE und auch isoliert startet, wird man unter (in meinem Fall) Windows 10 gefragt, ob man Traffic zulassen will. Das klicke ich brav an. Was kann man denn noch mehr machen?
Denn irgendwann wird es auch unpraktikabel. Wenn man ein Programm z.B. verkaufen will und dann zig Einstellungen ändern und das in ein Handbuch schreiben muss. Außerdem kommt das Paket an dem Rechner rein und es geht auch raus...
Jetzt bin ich völlig ratlos!
rage2002 - Do 09.03.17 12:05
Hallo
Vielen Dank für Deine Arbeit. Ich benutze einen MC mit unterschiedlichen Lan-Controllern und habe mir mit den üblichen UDP-Komponeten die Zähne ausgebissen ein einer Kommunikation am selben Port. Dank Deiner Komponente läuft es jetzt.
cu rage
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2024 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!