Avatar billede morten_s Nybegynder
18. juni 2002 - 12:08 Der er 10 kommentarer og
1 løsning

Dynamisk datastruktur af ClientSocket

Jeg har et program med en ServerSocket hvor et antal Clienter udefra kan connecte sig op
Meningen er så at ServerSocket’en skal ’stille’ videre til en anden IPAdr+Port.

ServerSocket’en skal altså fungere som et slags relæ eller knudepunkt hvor datastrømmen flyder
Igennem, jeg kan sagtens få det til at virke med flere Clienter ind i Serveren og en udgående linie idet jeg kan adskille de forskellige Clienter fra hinanden med det unike nr. som serveren tildeler med Socket.SocketHandle.

Mit problem er at oprette flere linier ud, hvordan får jeg fat i den rigtige udgående linies OnRead event og sendt hvad der kommer ind til den rigtige indgående Client via min ServerSocket ?
Avatar billede morten_s Nybegynder
18. juni 2002 - 12:09 #1
Der gives kun point til svar der kan bruges in real life ;-))
Avatar billede borrisholt Novice
18. juni 2002 - 12:37 #2
bruger du Indy ?

Jens B
Avatar billede morten_s Nybegynder
18. juni 2002 - 12:40 #3
Nej bare en almindelig ClientSocket, jeg skal køre unBlocked så Indy synes jeg ikke er anvendeligt
Avatar billede borrisholt Novice
18. juni 2002 - 12:42 #4
Så pak dit Indy ind i Tråde !
Avatar billede morten_s Nybegynder
18. juni 2002 - 12:43 #5
Jens> Jeg kender ikke min ATerminator derfor synes jeg det er et problem
Avatar billede morten_s Nybegynder
18. juni 2002 - 12:48 #6
Jens> Jeg skal også sende fra min Server ud igennem Client, kan heller ikke lige se konstruktionen på tråden for mig
Avatar billede borrisholt Novice
18. juni 2002 - 13:02 #7
Den Speedtest jeg lavede til TDC den virker på den måde ... Og den er lavedet på Indy !

Jens B
Avatar billede morten_s Nybegynder
18. juni 2002 - 13:23 #8
Jens> Selvfølgelig kan det lade sig gøre.....bare lige hvordan ;-(
Avatar billede morten_s Nybegynder
18. juni 2002 - 13:38 #9
Kan der ikke laves noget i denne stil ?
type
    ClientRec = record
    Client: TClientSocket;
    Host: String;
    Port: Integer;
    Handle: Integer;
  end;

var
  ClientArray: array[1..5] of ClientRec;

men hvordan får jeg den connected til host + port ?
og hvordan får jeg fat i dens event ??
Avatar billede morten_s Nybegynder
18. juni 2002 - 13:45 #10
Connecte kan jeg fint:
procedure TForm1.Button4Click(Sender: TObject);
begin
  if ClientArray[1].Client = nil then
  begin
    ClientArray[1].Client := TClientSocket.Create(self);
    ClientArray[1].Host := 'localhost';
    ClientArray[1].Port := 800;
    ClientArray[1].Client.Host := ClientArray[1].Host;
    ClientArray[1].Client.Port := ClientArray[1].Port;
    ClientArray[1].Client.Active := True;
  end;
end;

Men hvordan får jeg fat i OnRead og OnWrite event ?
Avatar billede morten_s Nybegynder
19. juni 2002 - 08:06 #11
Koden er her hvis andre skulle mangle ;-)

Princip: Når en client connecter sig til serveren oprettes en linie ud (Client) som har den indgående clients Socket.SocketHandle i dens Tag nr

unit uClientArray;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ScktComp, StdCtrls;

type
  TForm1 = class(TForm)
    ssRelae: TServerSocket;
    ssDummy: TServerSocket;
    Memo1: TMemo;
    Memo2: TMemo;
    Button1: TButton;
    procedure ssRelaeClientConnect(Sender: TObject;
      Socket: TCustomWinSocket);
    procedure ssRelaeClientDisconnect(Sender: TObject;
      Socket: TCustomWinSocket);
    procedure csOutConnect(Sender: TObject; Socket: TCustomWinSocket);
    procedure csOutRead(Sender: TObject; Socket: TCustomWinSocket);
    procedure csOutDisconnect(Sender: TObject; Socket: TCustomWinSocket);
    procedure ssRelaeClientRead(Sender: TObject; Socket: TCustomWinSocket);
    procedure ssDummyClientRead(Sender: TObject; Socket: TCustomWinSocket);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
   
  end;


var
  Form1: TForm1;
 

implementation

{$R *.dfm}

procedure TForm1.ssRelaeClientConnect(Sender: TObject;
  Socket: TCustomWinSocket);
var
  HandleIn: Integer;
begin
  HandleIn := Socket.SocketHandle;
  //Memo1.Lines.Add('connect from: '+IntToStr(HandleIn));
  with TClientSocket.Create(Form1) do
  begin
    Host := 'localhost';
    Port := 801;
    Tag := HandleIn;
    OnConnect := csOutConnect;
    OnRead := csOutRead;
    OnDisconnect := csOutDisconnect;
    Active := True;
  // ShowMessage('csOut created: '+IntToStr(Tag) );
  end;
end;

procedure TForm1.ssRelaeClientDisconnect(Sender: TObject;
  Socket: TCustomWinSocket);
var
  i, HandelIn : integer;
  cs: TClientSocket;
begin
  HandelIn := Socket.SocketHandle;
  Memo1.Lines.Add('disconnect from: '+IntToStr(HandelIn));
  for i := 0 to ComponentCount-1 do
  begin
    if (Components[i] is TClientSocket) then
    begin
      cs := (Components[i] as TClientSocket);
      if cs.Tag = HandelIn then
        cs.Active := False

    end;
  end;
end;

procedure TForm1.csOutConnect(Sender: TObject; Socket: TCustomWinSocket);
var
  cs : TClientSocket;
begin
  if (Sender is TClientSocket) then
  begin
    cs := (Sender as TClientSocket);
    Memo1.Lines.Add('Connect from: '+IntToStr(cs.Tag));
  end;
end;

procedure TForm1.csOutRead(Sender: TObject; Socket: TCustomWinSocket);
var
  i, HandelIn : Integer;
  cs : TClientSocket;
begin
  if (Sender is TClientSocket) then
  begin
    cs := (Sender as TClientSocket);
    for i := 0 to ssRelae.Socket.ActiveConnections -1 do
      if cs.Tag = ssRelae.Socket.Connections[i].SocketHandle then
        ssRelae.Socket.Connections[i].SendText(Socket.ReceiveText);
  end;
end;


procedure TForm1.csOutDisconnect(Sender: TObject;
  Socket: TCustomWinSocket);
var
  cs : TClientSocket;
begin
  if (Sender is TClientSocket) then
  begin
    cs := (Sender as TClientSocket);
    //ShowMessage('On disconnect'+IntToStr(cs.Tag));
    //HUSK DU MANGLER METODE TIL AT FREE MED
  end;
end;

procedure TForm1.ssRelaeClientRead(Sender: TObject;
  Socket: TCustomWinSocket);
var
  i, HandelIn : integer;
  inText : String;
  cs: TClientSocket;
begin
  HandelIn := Socket.SocketHandle;
  InText := Socket.ReceiveText;
  Memo1.Lines.Add(IntToStr(HandelIn) + ' Mesage: '+inText);
  for i := 0 to ComponentCount-1 do
  begin
    if (Components[i] is TClientSocket) then
    begin
      cs := (Components[i] as TClientSocket);
      if cs.Tag = HandelIn then
        cs.Socket.SendText(inText)
    end;
  end;
end;

procedure TForm1.ssDummyClientRead(Sender: TObject;
  Socket: TCustomWinSocket);
var
  inStr : String;
  i, Con : Integer;
begin
  Con := Socket.SocketHandle;
  inStr := Socket.ReceiveText;
  Memo2.Lines.Add(inStr);
  for i := 0 to ssDummy.Socket.ActiveConnections - 1 do
    if Con = ssDummy.Socket.Connections[i].SocketHandle then
      ssDummy.Socket.Connections[i].SendText(inStr);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  i : integer;
  cs : TClientSocket;
begin
  for i := 0 to ComponentCount-1 do
  begin
    if (Components[i] is TClientSocket) then
      if not (Components[i] as TClientSocket).Active then
        (Components[i] as TClientSocket).Free;
  end;
end;
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester