![]() |
2 UDP server auf demselben Port ?
Hi,
gibt es einen Weg 2 UDP server (auf einem Rechner) zu erlauben über den selben Port lauschen ? Hintergrund: ich möchte mit einem Steuerprogramm verschiedene Programme per UDP broadcast ansprechen... das funktioniert ja soweit auch ohne Probleme - aber sobald die Programme auf demselben Rechner sind, dann kann nur jeweils ein UDP server auf den Port connected werden... Wie löst ihr sowas ? Da es häufig dieselben Daten sind wollte ich eigentlich nicht verschiedene Ports nutzen, da ich ja sonst den Trafffic künstlich erhöhe... Danke Ralf |
Re: 2 UDP server auf demselben Port ?
Zwei Server die auf einem Port lauschen ist meines Wissens nicht möglich.
Ist es nicht möglich, das der eine Server die Daten zum zweiten Server weiterreicht? Grüße Klaus |
Re: 2 UDP server auf demselben Port ?
ein Port steht in der Regel für einen Service. Dementsprechend sollten verschiedene Dienste (Programme die verschiedenes machen) auch auf verschiedenen Ports laufen. Und wenn Programm auf einem Rechner miteinander kommunizieren sollen gibt es andee Lösungen wie pipes, messages etc.
|
Re: 2 UDP server auf demselben Port ?
Zitat:
Delphi-Quellcode:
unit AdsNotify;
interface uses SysUtils, Classes, winsock, windows; type ESocketError = class(EOSError); TrcLog = procedure(s:string) of object; TrcNotifyEvent = procedure (Sender:TObject;tables:string) of object; TReceiveThread = class(TThread) private { Private declarations } fPort:integer; FOnReceive: TrcNotifyEvent; FOnLog: TrcLog; procedure SetOnLog(const Value: TrcLog); procedure SetOnReceive(const Value: TrcNotifyEvent); protected procedure Execute; override; procedure DoReceive; procedure Log(s:string); public msg:string; constructor Create(Port:integer); property OnReceive:TrcNotifyEvent read FOnReceive write SetOnReceive; property OnLog:TrcLog read FOnLog write SetOnLog; end; tAdsNotify = class(TComponent) private FPort: integer; FOnNotification: TrcNotifyEvent; rcThread:TReceiveThread; procedure SetPort(const Value: integer); procedure SetOnNotification(const Value: TrcNotifyEvent); { Private declarations } protected { Protected declarations } procedure DoNotification; public { Public declarations } constructor Create(Owner:TComponent; Port:integer=0); reintroduce; published { Published declarations } property Port:integer read FPort write SetPort; property OnNotification:TrcNotifyEvent read FOnNotification write SetOnNotification; end; resourcestring SSocketError = 'Socket Error. Code: %d.' + sLineBreak + '%s'; SUnkSocketError = 'A call to a socket function failed'; procedure Register; implementation procedure Register; begin RegisterComponents('Advantage', [tAdsNotify]); end; { tAdsNotify } constructor tAdsNotify.Create(Owner: TComponent; Port: integer=0); begin inherited Create(Owner); rcThread:=nil; SetPort(Port); end; procedure tAdsNotify.DoNotification; var tables:string; begin if assigned(rcThread) then begin tables:=rcThread.msg; rcthread.msg:=''; if assigned(FOnNotification) then FOnNotification(self,tables); end; end; procedure tAdsNotify.SetOnNotification(const Value: TrcNotifyEvent); begin FOnNotification := Value; if assigned(rcThread) then rcThread.OnReceive:=OnNotification; end; procedure tAdsNotify.Setport(const Value: integer); begin if assigned(rcThread) then begin rcThread.Terminate; end; Fport := Value; if FPort>0 then begin rcThread:=TReceiveThread.Create(FPort); rcThread.OnReceive:=OnNotification; rcThread.FreeOnTerminate:=true; rcThread.Resume; end; end; { TReceiveThread } procedure RaiseSocketError(E: Integer); var Error: ESocketError; begin if E <> 0 then Error := ESocketError.CreateResFmt(@SSocketError, [E, SysErrorMessage(E)]) else Error := ESocketError.CreateRes(@SUnkSocketError); Error.ErrorCode := E; raise Error; end; procedure RaiseLastSocketError; begin RaiseSocketError(WSAGetLastError); end; procedure InitWinSock; var Data: TWSAData; E: Integer; begin E := WSAStartup(1, Data); if E <> 0 then RaiseSocketError(E); end; function MachineName: String; var Buf: array[0..MAX_COMPUTERNAME_LENGTH] of Char; Len: Cardinal; begin Len := SizeOf(Buf); if GetComputerName(Buf, Len) then SetString(Result, Buf, Len) else Result := '?'; end; function CreateSocket(port:integer):TSocket; var Sock: TSocket; Opt: Integer; LocalAddr:TSockAddr; begin InitWinSock; Sock := socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if Sock = INVALID_SOCKET then RaiseLastSocketError; Opt := 1; if setsockopt(Sock, SOL_SOCKET, SO_REUSEADDR, @Opt, SizeOf(Opt)) <> 0 then RaiseLastSocketError; LocalAddr.sin_family := AF_INET; LocalAddr.sin_port := htons(port); LocalAddr.sin_addr.S_addr := INADDR_ANY; if bind(Sock, LocalAddr, SizeOf(LocalAddr)) <> 0 then RaiseLastSocketError; result:=sock; end; function Receive(var Sock:TSocket;var s:string;var PeerAddr:TSockAddr):boolean; var PeerAddrLen: Integer; MsgBuf: array[0..511] of Char; MsgLen: Integer; begin PeerAddrLen := SizeOf(PeerAddr); MsgLen := recvfrom(Sock, MsgBuf, SizeOf(MsgBuf), 0, PeerAddr, PeerAddrLen); if MsgLen>0 then begin SetString(s, MsgBuf, MsgLen); result:=true; end else begin result:=false; end; end; constructor TReceiveThread.Create(Port: integer); begin inherited Create(true); fPort:=Port; end; procedure TReceiveThread.DoReceive; begin if assigned(FOnReceive) then begin FOnReceive(self, msg); msg:=''; end; end; procedure TReceiveThread.Execute; var Sock: TSocket; PeerAddr: TSockAddr; PeerAddrLen: Integer; MsgBuf: array[0..511] of Char; MsgLen: Integer; begin try Sock:=CreateSocket(fport); while not Suspended do begin PeerAddrLen := SizeOf(PeerAddr); MsgLen := recvfrom(Sock, MsgBuf, SizeOf(MsgBuf), 0, PeerAddr, PeerAddrLen); if MsgLen > 0 then begin SetString(msg, MsgBuf, MsgLen); DoReceive; end; end; except on E:Exception do log(e.Message); end; end; procedure TReceiveThread.Log(s: string); begin end; procedure TReceiveThread.SetOnLog(const Value: TrcLog); begin FOnLog := Value; end; procedure TReceiveThread.SetOnReceive(const Value: TrcNotifyEvent); begin FOnReceive := Value; end; end. |
Re: 2 UDP server auf demselben Port ?
@SirThornberry - beim lauschen auf einem Port macht das bei UDP-Broadcast schon Sinn, wenn die Programme dieselben Ausgangsdaten benötigen, dann reicht ein Broadcast um verschiedene Programme zu bedienen - und der Vorteil ist, dass
es dann auch egal ist ob die Progs jetzt auf einem oder auf verschiedenen Rechnern im Netz laufen - @Klaus01 - mehrere UDP-Server die auf einem Port lauschen sind möglich z.B. die ICS TWSocket - Komponente hat wie ich gerade hearugefunden habe eine Eigenschaft "ReuseAddr" bei True funktioniert das ausgezeichnet.. @joachimd - danke für den Code, da muß ich mich erst mal reindenken Die Frage die bleibt ist, ob es nicht doch möglich ist, dass auch über die Indys zu realisieren... habe aber leider noch nicht den richtigen Schalter gefunden... und die Doku zu den Indys incl. Indy in "Depth" ist leider sehr oberflächlich.. Schönen Abend Ralf |
Re: 2 UDP server auf demselben Port ?
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:55 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz