![]() |
Indy - Server schickt Nachricht an alle Clients
Ist es mit Indy möglich vom Server per Knopfdruck eine Nachricht an alle verbundenen Clients zu schicken?
Delphi-Quellcode:
gibt mir immer nen E/A-Fehler
procedure TfrmServer.Button1Click(Sender: TObject);
begin with TCPServer do Writeln('dasdasd'); end; |
Re: Indy - Server schickt Nachricht an alle Clients
Ich würde alle Clients in einem Array halten und die dann in einer Schleife durchgehen und dier Nachricht schicken.
|
Re: Indy - Server schickt Nachricht an alle Clients
Aber wie kann ich vom Server aus ne Nachrich an den Client schicken?
Oder muss ich mir in dem Moment wo der Client sich verbinden mir irgendwo die Client-Adresse holen und die speichern?? |
Re: Indy - Server schickt Nachricht an alle Clients
Ach so. Das geht wohl nur, wenn die Clients auch gleichzeitig Sever sind für den eigentlichen Server und umgekehrt. Aber in Netzwerkdingen bin ich nicht so fit.
|
Re: Indy - Server schickt Nachricht an alle Clients
Bei ServerSocket geht das so:
Delphi-Quellcode:
Wie es bei Indy gemacht wird - keine ahnung, aber bestimmt ähnlich
for i:=0 to SS1.Socket.ActiveConnections-1 do begin
SS1.Socket.Connections[i].SendText('BLABLABLA'); end; |
Re: Indy - Server schickt Nachricht an alle Clients
habe in 2 threads schonmal geschrieben wie man das macht ohne in beiden applikationen server und client doppelt zu verwenden
|
Re: Indy - Server schickt Nachricht an alle Clients
![]() Guck mal bei den beispielen... das ist TCPServer-Client Demo dabei. Hier ein ausschnitt:
Delphi-Quellcode:
Ich glaube mal, da ist das dabei, was du brauchst.
procedure TServerFrmMain.ServerExecute(AThread: TIdPeerThread);
var ActClient, RecClient: PClient; CommBlock, NewCommBlock: TCommBlock; RecThread: TIdPeerThread; i: Integer; begin if not AThread.Terminated and AThread.Connection.Connected then begin AThread.Connection.ReadBuffer (CommBlock, SizeOf (CommBlock)); ActClient := PClient(AThread.Data); ActClient.LastAction := Now; // update the time of last action if (CommBlock.Command = 'MESSAGE') or (CommBlock.Command = 'DIALOG') then begin // 'MESSAGE': A message was send - forward or broadcast it // 'DIALOG': A dialog-window shall popup on the recipient's screen // it's the same code for both commands... if CommBlock.ReceiverName = '' then begin // no recipient given - broadcast Protocol.Lines.Add (TimeToStr(Time)+' Broadcasting '+CommBlock.Command+': "'+CommBlock.Msg+'"'); NewCommBlock := CommBlock; // nothing to change ;-)) with Clients.LockList do try for i := 0 to Count-1 do // iterate through client-list begin RecClient := Items[i]; // get client-object RecThread := RecClient.Thread; // get client-thread out of it RecThread.Connection.WriteBuffer(NewCommBlock, SizeOf(NewCommBlock), True); // send the stuff end; finally Clients.UnlockList; end; end else begin // receiver given - search him and send it to him NewCommBlock := CommBlock; // again: nothing to change ;-)) Protocol.Lines.Add(TimeToStr(Time)+' Sending '+CommBlock.Command+' to "'+CommBlock.ReceiverName+'": "'+CommBlock.Msg+'"'); with Clients.LockList do try for i := 0 to Count-1 do begin RecClient:=Items[i]; if RecClient.DNS=CommBlock.ReceiverName then // we don't have a login function so we have to use the DNS (Hostname) begin RecThread:=RecClient.Thread; RecThread.Connection.WriteBuffer(NewCommBlock, SizeOf(NewCommBlock), True); end; end; finally Clients.UnlockList; end; end; end else begin // unknown command given Protocol.Lines.Add (TimeToStr(Time)+' Unknown command from "'+CommBlock.MyUserName+'": '+CommBlock.Command); NewCommBlock.Command := 'DIALOG'; // the message should popup on the client's screen NewCommBlock.MyUserName := '[Server]'; // the server's username NewCommBlock.Msg := 'I don''t understand your command: "'+CommBlock.Command+'"'; // the message to show NewCommBlock.ReceiverName := '[return-to-sender]'; // unnecessary AThread.Connection.WriteBuffer (NewCommBlock, SizeOf (NewCommBlock), true); // and there it goes... end; end; end |
Re: Indy - Server schickt Nachricht an alle Clients
Zitat:
|
Re: Indy - Server schickt Nachricht an alle Clients
Zitat:
![]() |
Re: Indy - Server schickt Nachricht an alle Clients
ich hab selber (vor 1. woche) versucht sowas zu bauen und jetzt klapts alles auch:
Client:
Delphi-Quellcode:
Server:
unit UMain;
interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, IdAntiFreezeBase, IdAntiFreeze; // ------- NETWORK PROTOKOL -------- // v001 type TNetConfig = record data : boolean; CMD : string[20]; SIP : string[16]; DIP : string[16]; end; // --------------------------------- type TForm1 = class(TForm) tcpClient: TIdTCPClient; GroupBox1: TGroupBox; btnConnect: TButton; edtHost: TEdit; edtPort: TEdit; edtUser: TEdit; edtPass: TEdit; btnDisconnect: TButton; Label1: TLabel; Label2: TLabel; memLog: TMemo; IdAntiFreeze1: TIdAntiFreeze; edtSend: TEdit; btnSend: TButton; procedure FormDestroy(Sender: TObject); procedure btnConnectClick(Sender: TObject); procedure btnDisconnectClick(Sender: TObject); procedure btnSendClick(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; inloop : integer = 1; //default value = 1 (while in thread = stop !) TOut : THandle; implementation {$R *.DFM} function netscan(P : pointer): integer; var Data:TNetConfig; begin // Code ! while inloop =0 do begin //read data from server Form1.tcpclient.ReadBuffer(Data,sizeof(Data)); if Data.data = false then Form1.memLog.Lines.add('STR:'+Data.CMD) else Form1.memLog.Lines.add('CMD:'+Data.CMD); // read thread status (inloop value) sleep(300); Form1.Label1.Caption := inttostr(inLoop); end; end; procedure TForm1.FormDestroy(Sender: TObject); begin //set inLoop to 1 (stops while in thread) InterlockedExchange(inLoop, 1); // TCP Disconnection ! tcpclient.Disconnect; end; procedure TForm1.btnConnectClick(Sender: TObject); var ThreadID: LongWord; p: Pointer; begin // Server-IP (Data from edtHost) tcpclient.Host := edtHost.Text; // Server-Port (Data from edtPort) tcpclient.Port := strtoint(edtPort.Text); // Connection to server tcpClient.Connect; // If connection is succesfull, then start the thread ! if tcpClient.Connected then begin memLog.Lines.Add('Connected to server!'); //set inLoop to 0 (while in thread can run) InterlockedExchange(inLoop, 0); //start thread ! TOut := BeginThread(nil, 0, @netscan, p, 0, ThreadID); end; end; procedure TForm1.btnDisconnectClick(Sender: TObject); var ExitCode: DWORD; begin InterlockedExchange(inLoop, 1); TerminateThread(Tout,ExitCode); tcpClient.Disconnect; end; procedure TForm1.btnSendClick(Sender: TObject); var Data:TNetConfig; begin if pos('/',edtSend.Text) = 1 then Data.data := true else Data.data := false; Data.CMD := edtSend.Text; Data.SIP := tcpClient.Socket.Binding.IP; Data.DIP := tcpClient.Host; tcpClient.WriteBuffer(Data,sizeof(Data)); end; end.
Delphi-Quellcode:
unit UMain;
interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, ComCtrls, IdThreadMgr, IdThreadMgrDefault, IdBaseComponent, IdComponent, IdTCPServer, StdCtrls; // ---- INTERN CLIENT RECORDS ------ type TSimpleClient = class(TObject) IP, Name : String; ID : Integer; Thread : Pointer; end; // --------------------------------- // ------- NETWORK PROTOKOL -------- // v001 type TNetConfig = record data : boolean; CMD : string[20]; SIP : string[16]; DIP : string[16]; end; // --------------------------------- type TMain = class(TForm) tcpServer: TIdTCPServer; IdThreadMgrDefault1: TIdThreadMgrDefault; btnStart: TButton; Memo1: TMemo; lbClients: TListBox; lblClientName: TLabel; lblClientDNS: TLabel; lblClientID: TLabel; edtSend: TEdit; Button1: TButton; Edit1: TEdit; procedure FormCreate(Sender: TObject); procedure tcpServerConnect(AThread: TIdPeerThread); procedure btnStartClick(Sender: TObject); procedure tcpServerExecute(AThread: TIdPeerThread); procedure tcpServerDisconnect(AThread: TIdPeerThread); procedure lbClientsClick(Sender: TObject); procedure Button1Click(Sender: TObject); private { Private declarations } public Clients : TList; end; var Main: TMain; implementation {$R *.DFM} procedure TMain.FormCreate(Sender: TObject); begin Clients := TList.Create; end; procedure TMain.tcpServerConnect(AThread: TIdPeerThread); var Client : TSimpleClient; Data : TNetConfig; begin Memo1.Lines.Add('User connected'); // Welcome MSG Data.data := false; Data.CMD := 'Welcome to Server'; Data.SIP := AThread.Connection.Socket.Binding.IP; Data.DIP := AThread.Connection.Socket.Binding.PeerIP; AThread.Connection.WriteBuffer(Data,sizeof(Data)); // Create a client object Client := TSimpleClient.Create; // Assign its default values Client.IP := Athread.Connection.Socket.Binding.PeerIP; Client.Name := 'Logging In'; Client.ID := lbClients.Items.Count; Client.Thread := AThread; lbClients.Items.Add(Client.IP); AThread.Data := Client; Clients.Add(Client); end; procedure TMain.btnStartClick(Sender: TObject); begin tcpServer.DefaultPort := 10024; tcpServer.Active := true; memo1.Lines.add('Server start'); end; procedure TMain.tcpServerExecute(AThread: TIdPeerThread); var Data : TNetConfig; begin AThread.Connection.ReadBuffer(Data,sizeof(Data)); if Data.data = false then Memo1.Lines.add('From:'+Data.SIP+' To:'+Data.DIP+' STR:'+Data.CMD) else Memo1.Lines.add('From:'+Data.SIP+' To:'+Data.DIP+' CMD:'+Data.CMD) end; procedure TMain.tcpServerDisconnect(AThread: TIdPeerThread); var Client : TSimpleClient; begin { Client := Pointer(AThread.Data); memo1.Lines.Add('User ['+ Client.ip +'] disconnected'); Clients.Delete(Client.ID); lbClients.Items.Delete(lbClients.Items.IndexOf(Client.IP)); Client.Free; AThread.Data := nil; } end; procedure TMain.lbClientsClick(Sender: TObject); var Client : TSimpleClient; begin if lbClients.ItemIndex = -1 then exit; Client := Clients.Items[lbClients.ItemIndex]; lblClientName.Caption := Client.Name; lblClientDNS.Caption := Client.IP; lblClientID.Caption := inttostr(Client.ID); end; procedure TMain.Button1Click(Sender: TObject); var Client : TSimpleClient; Data : TNetConfig; begin if (lbClients.ItemIndex <> -1) then begin Client := Clients.Items[lbClients.ItemIndex]; if pos('/',edtSend.Text) = 1 then Data.data := true else Data.data := false; Data.CMD := edtSend.Text; Data.SIP := TIdPeerThread(Client.Thread).Connection.Socket.Binding.IP; Data.DIP := TIdPeerThread(Client.Thread).Connection.Socket.Binding.PeerIP; TIdPeerThread(Client.Thread).Connection.WriteBuffer(Data,sizeof(Data)); end; end; end. Hilfts ? PS: Hab den code noch nicht ganz fertig (sind noch sachen da di raussollen ex: inloop var!) BTW: Hab noch nem problem mit dem OnDisconnect im Server ... er findet den zu löschende user nicht ! Woran kann das liegen ? |
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:09 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