AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Netzwerke Delphi 2 UDP server auf demselben Port ?
Thema durchsuchen
Ansicht
Themen-Optionen

2 UDP server auf demselben Port ?

Ein Thema von th_bone · begonnen am 10. Apr 2007 · letzter Beitrag vom 11. Apr 2007
Antwort Antwort
th_bone

Registriert seit: 16. Jun 2004
172 Beiträge
 
Delphi 2005 Professional
 
#1

2 UDP server auf demselben Port ?

  Alt 10. Apr 2007, 12:41
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
  Mit Zitat antworten Zitat
Klaus01

Registriert seit: 30. Nov 2005
Ort: München
5.755 Beiträge
 
Delphi 10.4 Sydney
 
#2

Re: 2 UDP server auf demselben Port ?

  Alt 10. Apr 2007, 12:48
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
Klaus
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#3

Re: 2 UDP server auf demselben Port ?

  Alt 10. Apr 2007, 13:07
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.
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat
Benutzerbild von joachimd
joachimd

Registriert seit: 17. Feb 2005
Ort: Weitingen
672 Beiträge
 
Delphi 10.4 Sydney
 
#4

Re: 2 UDP server auf demselben Port ?

  Alt 10. Apr 2007, 13:12
Zitat von th_bone:
gibt es einen Weg 2 UDP server (auf einem Rechner) zu erlauben über den selben Port lauschen ?
Du darfst den Port nicht exklusiv binden. Ich habe mal sowas für die Notification in ADS in eine Komponente (Komponente kapselt einen Empfangs-Thread) gepackt. Die kannst Du Dir für Deine Zwecke abändern. Verantwortlich ist in CreateSocket das SO_REUSEADDR.
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.
Joachim Dürr
Joachim Dürr Softwareengineering
http://www.jd-engineering.de
  Mit Zitat antworten Zitat
th_bone

Registriert seit: 16. Jun 2004
172 Beiträge
 
Delphi 2005 Professional
 
#5

Re: 2 UDP server auf demselben Port ?

  Alt 10. Apr 2007, 19:30
@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
  Mit Zitat antworten Zitat
Benutzerbild von joachimd
joachimd

Registriert seit: 17. Feb 2005
Ort: Weitingen
672 Beiträge
 
Delphi 10.4 Sydney
 
#6

Re: 2 UDP server auf demselben Port ?

  Alt 11. Apr 2007, 08:04
Zitat von th_bone:
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..
IIRC geht das mit den Indy-Komponenten nicht, da es dort nicht als Property herausgeführt ist. Ich hatte mal eine Diskussion mit Hadi und Kudzu darüber und ihnen dann (auch nach Anfrage in den NG) das obige Beispiel gezeigt.
Joachim Dürr
Joachim Dürr Softwareengineering
http://www.jd-engineering.de
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:14 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz