AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Netzwerke Delphi Chatserver mit TServerSocket
Thema durchsuchen
Ansicht
Themen-Optionen

Chatserver mit TServerSocket

Offene Frage von "Capa"
Ein Thema von Capa · begonnen am 3. Apr 2010 · letzter Beitrag vom 5. Apr 2010
Antwort Antwort
Seite 1 von 2  1 2      
Capa

Registriert seit: 26. Okt 2003
102 Beiträge
 
RAD-Studio 2010 Arc
 
#1

Chatserver mit TServerSocket

  Alt 3. Apr 2010, 10:24
Ich eröffne diesen Thread weniger als fragethread sondern eher als hilfethread für
die vielen Hilfesuchenden zum thema "TServersocket/TClientsocket und Netzwerk/Internet Chat"

Hab mich mal eine weile hingesetzt und mir so ein wenig überlegt wie man am besten nen Server
mit mehreren Extras baut. Das ganze hat nicht lange gedauert und der erste ansatz war fertig.
Zuerst einmal hab ich eine unit geschrieben die ich für die Userliste benutze.
Unteranderem hab ich hier mehrere Funktionen eingebaut womit ich zum bsp eine Nicklist
erstellen und aktuell halten kann. Ändern des Nicknamens, Senden von Text an alle oder auch nur
an bestimmte Personen.
Mag sein das es für einige nicht die beste art ist einige sachen zu lösen aber ich bin auch für vorschläge offen ^^.

Datei: userlist.pas
Delphi-Quellcode:
unit userlist;

interface

uses Windows, Messages, SysUtils, Variants, Classes, ScktComp, StdCtrls, Dialogs;

// *********************************************
// ******** TUserdata **************************
// *********************************************
type
  TUserdata = record
    Username: string[12]; // Name des Users
    Userip: string; // Ip des Clienten
    Userport: string; // Port des Clienten von dem aus er Connected ist
    Userid: string; // id bestehend aus ip:port zur genauen identifizierung des Users (Cloneschutz)
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;
// *********************************************
// ******** TUserlist **************************
// *********************************************
type
  TUserlist = class
    Userdaten: array[1..250] of TUserdata;
    Count: integer;
    procedure Adduser(name,ip, port: string; mylist:TListBox); overload;
    procedure Adduser(name,ip, port: string); overload;
    procedure Deleteuser(ip, port: string; mylist:TListBox); overload;
    procedure Deleteuser(ip, port: string); overload;
    procedure Sendtextto(code, ip, port, text: string; Socket: TServerSocket);
    procedure Broadcast(text: string; Socket: TServerSocket);
    procedure Clear;
    procedure Sendfile(ip, port: string; filename: pchar; Socket: TServerSocket);
    function GetUsernamebyid(id: string): string;
    function GetUserIdbyname(name: string): string;
    function GetUseripbyid(id: string): string;
    function GetUserportbyid(id: string): string;
    function ChangeNickName(oldname,newname: string; Socket: TServerSocket; mylist: TListbox): string;
    function GetFileSize(const FileName: String): Int64;
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

implementation

// *********************************************
// ******** TUserlist Proceduren ***************
// *********************************************
procedure TUserlist.Clear;
  var a: integer;
begin
  for a := 1 to length(Userdaten) - 1 do
  begin
    Userdaten[a].Username := '';
    Userdaten[a].Userip := '';
    Userdaten[a].Userport := '';
    Userdaten[a].Userid := '';
    Count := 0;
  end;
end;

function TUserlist.ChangeNickName(oldname,newname: string; Socket: TServerSocket; mylist: TListbox): string;
  var a,b,c: integer;
begin
  b := 0;
  for a := 1 to length(Userdaten) - 1 do
  begin
    if (Userdaten[a].Username = oldname) then
      c := a;
    if (Userdaten[a].Username = newname) then
    begin
      Result := '*** Name bereits vergeben! ***';
      b := 1;
      Exit;
    end;
  end;
  if (b = 0) then
  begin
    for a := 0 to mylist.Count - 1 do
    begin
      if (mylist.Items[a] = oldname) then
        mylist.Items[a] := newname;
    end;
    Userdaten[c].Username := newname;
    Broadcast('Namechange: '+oldname+' => '+newname,Socket);
    Result := '';
  end;
end;

function TUserlist.GetFileSize(const FileName: String): Int64;
var srec: TSearchRec;
begin
  Result := -1;
  if FindFirst(FileName, faAnyFile, srec) = 0 then
  begin
    try
      result := srec.Size;
    finally
      FindClose(srec);
    end;
  end;
end;

procedure TUserlist.Adduser(name,ip, port: string; mylist:TListBox);
  var a: integer;
begin
  for a := 1 to length(Userdaten) - 1 do
  begin
    if (Userdaten[a].Userip = '') then
    begin
      Userdaten[a].Username := name;
      Userdaten[a].Userip := ip;
      Userdaten[a].Userport := port;
      Userdaten[a].Userid := ip+':'+port;
      mylist.Items.Add(name);
      Count := Count+1;
      exit;
    end;
  end;
end;

procedure TUserlist.AddUser(name,ip,port: string);
  var a: integer;
begin
  for a := 1 to length(Userdaten) - 1 do
  begin
    if (Userdaten[a].Userip = '') then
    begin
      Userdaten[a].Username := name;
      Userdaten[a].Userip := ip;
      Userdaten[a].Userport := port;
      Userdaten[a].Userid := ip+':'+port;
      Count := Count+1;
      exit;
    end;
  end;
end;

procedure TUserlist.Deleteuser(ip, port: string; mylist:TListBox);
  var a: integer;
     xu: string;
begin
  try
    xu := GetUsernamebyid(ip+':'+port);
    for a := mylist.Count - 1 downto 0 do
    begin
      if (mylist.Items[a] = xu) then
      begin
        mylist.Items.Move(a,mylist.Count-1);
        mylist.Items.delete(mylist.count-1);
        mylist.Refresh;
      end;
    end;
  finally
    for a := 1 to length(Userdaten) - 1 do
    begin
      if (Userdaten[a].Userid = ip+':'+port) then
      begin
        Userdaten[a].Username := '';
        Userdaten[a].Userip := '';
        Userdaten[a].Userport := '';
        Userdaten[a].Userid := '';
        Count := Count-1;
      end;
    end;
  end;
end;

procedure TUserlist.Deleteuser(ip, port: string);
  var a: integer;
begin
  for a := 1 to length(Userdaten) - 1 do
  begin
    if (Userdaten[a].Userid = ip+':'+port) then
    begin
      Userdaten[a].Username := '';
      Userdaten[a].Userip := '';
      Userdaten[a].Userport := '';
      Userdaten[a].Userid := '';
      Count := Count-1;
      Exit;
    end;
  end;
end;

procedure TUserlist.Sendtextto(code,ip, port, text: string; Socket: TServerSocket);
  var a: integer;
begin
  for a := 0 to socket.Socket.ActiveConnections - 1 do
  begin
    if ((socket.Socket.Connections[a].RemoteAddress = ip) AND (socket.Socket.Connections[a].RemotePort = StrToInt(port))) then
    begin
      socket.Socket.Connections[a].SendText(code+' '+text);
      exit;
    end;
  end;
end;

function TUserlist.GetUsernamebyid(id: string): string;
  var a: integer;
begin
  for a := 1 to length(Userdaten) - 1 do
  begin
    if (Userdaten[a].Userid = id) then
    begin
      result := Userdaten[a].Username;
      exit;
    end;
  end;
end;

function TUserlist.GetUseripbyid(id: string): string;
  var a: integer;
begin
  for a := 1 to length(Userdaten) - 1 do
  begin
    if (Userdaten[a].Userid = id) then
    begin
      result := Userdaten[a].Userip;
      exit;
    end;
  end;
end;

function TUserlist.GetUserportbyid(id: string): string;
  var a: integer;
begin
  for a := 1 to length(Userdaten) - 1 do
  begin
    if (Userdaten[a].Userid = id) then
    begin
      result := Userdaten[a].Userport;
      exit;
    end;
  end;
end;

function TUserlist.GetUserIdbyname(name: string): string;
  var a: integer;
begin
  for a := 1 to length(Userdaten) - 1 do
  begin
    if (Userdaten[a].Username = name) then
    begin
      result := Userdaten[a].Userid;
      exit;
    end;
  end;
end;

procedure TUserlist.Sendfile(ip, port: string; filename: pchar; Socket: TServerSocket);
  var a: integer;
begin
  for a := 0 to socket.Socket.ActiveConnections - 1 do
  begin
    socket.Socket.Connections[a].SendText('FILE '+filename+' SIZE '+IntToStr(GetFileSize(filename)));
    Socket.Socket.Connections[a].SendStream(TFileStream.Create(filename, fmOpenRead or fmShareDenyWrite));
  end;
end;

procedure TUserlist.Broadcast(text: string; Socket: TServerSocket);
  var a: integer;
begin
  for a := 0 to socket.Socket.ActiveConnections - 1 do
  begin
    socket.Socket.Connections[a].SendText(text);
  end;
end;
// *********************************************
// ******** TUserlist Proceduren ***************
// *********************************************

end.

Hier der Code des eigentlichen Programms:

Datei: unit1.pas
Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, userlist, ScktComp, StdCtrls, ExtCtrls, IdBaseComponent, IdComponent,
  IdTCPConnection, IdTCPClient, IdHTTP, Menus, ComCtrls, ClipBrd;

// *********************************************
// ******** TForm1 *****************************
// *********************************************
type
  TForm1 = class(TForm)
    Server: TServerSocket;
    HTTP: TIdHTTP;
    ListBox1: TListBox;
    Panel1: TPanel;
    Button1: TButton;
    Button2: TButton;
    Edit1: TEdit;
    ListBox2: TListBox;
    Splitter1: TSplitter;
    PopupMenu1: TPopupMenu;
    Kick1: TMenuItem;
    Ban1: TMenuItem;
    N1: TMenuItem;
    MSGTOUser1: TMenuItem;
    FILETOUser1: TMenuItem;
    N2: TMenuItem;
    INFOFROMUser1: TMenuItem;
    Button3: TButton;
    speichern: TSaveDialog;
    StatusBar1: TStatusBar;
    PopupMenu2: TPopupMenu;
    CopyText1: TMenuItem;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure ServerClientConnect(Sender: TObject; Socket: TCustomWinSocket);
    procedure ServerClientDisconnect(Sender: TObject; Socket: TCustomWinSocket);
    procedure Edit1KeyPress(Sender: TObject; var Key: Char);
    procedure ServerClientRead(Sender: TObject; Socket: TCustomWinSocket);
    procedure ServerClientError(Sender: TObject; Socket: TCustomWinSocket;
      ErrorEvent: TErrorEvent; var ErrorCode: Integer);
    procedure Button3Click(Sender: TObject);
    procedure PopupMenu1Popup(Sender: TObject);
    procedure PopupMenu2Popup(Sender: TObject);
    procedure CopyText1Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;
  Userliste: TUserlist;
  uid: integer;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
    HTTP.Get('http://www.*******/adminip.php?action=reactivate'); // Onlineupdate siehe extra hinweis unten
    ListBox1.Items.Add('*** Online-Update wurde durchgeführt! ***');
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  if (Server.Active) then
  begin
    Server.Close;
    ListBox1.Items.Add('*** Server wurde beendet! ***');
    Button2.Caption := 'Start Server';
    ListBox2.Clear;
    Userliste.Clear;
    uid := 1;
  end else begin
    Server.Open;
    ListBox1.Items.Add('*** Server wurde gestartet! ***');
    Button2.Caption := 'Stop Server';
    ListBox2.Clear;
    Userliste.Clear;
    uid := 1;
  end;
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
  if (speichern.Execute) then // Abspeichern des Server-Chat-Log's in eine Datei
    ListBox1.Items.SaveToFile(speichern.FileName);
end;

procedure TForm1.CopyText1Click(Sender: TObject);
begin
  Clipboard.AsText := ListBox1.Items[ListBox1.ItemIndex]; // eine kleine Kopierfunktion um zeilen aus dem Server-Chat-Log rauszukopieren
end;

procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
  if (key=#13) then // wenn "Enter" dann mache folgendes
  begin
    Userliste.Broadcast('Server: '+Edit1.Text,Server); // das was im Servereditfeld eingegeben wird wird hier an alle user geschickt
    ListBox1.Items.Add('*** Server: '+Edit1.Text+' ***'); // und hier wird es dem server selber ausgegeben
    Edit1.Clear;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Userliste := TUserlist.Create;
  Userliste.Clear;
  uid := 1;
end;

procedure TForm1.PopupMenu1Popup(Sender: TObject);
var x: string;
begin
  if (ListBox2.ItemIndex >= 0) then
  begin
    x := ListBox2.Items[ListBox2.ItemIndex];
    Popupmenu1.Items[0].Visible := True;
    Popupmenu1.Items[1].Visible := True;
    Popupmenu1.Items[3].Visible := True;
    Popupmenu1.Items[4].Visible := True;
    Popupmenu1.Items[6].Visible := True;
    Popupmenu1.Items[0].Caption := 'KICK '+x;
    Popupmenu1.Items[1].Caption := 'BAN '+x;
    Popupmenu1.Items[3].Caption := 'MSG TO '+x;
    Popupmenu1.Items[4].Caption := 'FILE TO '+x;
    Popupmenu1.Items[6].Caption := 'INFO FROM '+x;
  end else begin
    Popupmenu1.Items[0].Visible := False;
    Popupmenu1.Items[1].Visible := False;
    Popupmenu1.Items[3].Visible := False;
    Popupmenu1.Items[4].Visible := False;
    Popupmenu1.Items[6].Visible := False;
  end;
end;

procedure TForm1.PopupMenu2Popup(Sender: TObject);
var x: string;
begin
  if (ListBox1.ItemIndex >= 0) then
  begin
    x := ListBox1.Items[ListBox1.ItemIndex];
    Popupmenu2.Items[0].Visible := True;
  end else begin
    Popupmenu2.Items[0].Visible := False;
  end;
end;

procedure TForm1.ServerClientConnect(Sender: TObject; Socket: TCustomWinSocket);
begin
  Userliste.Adduser('User'+inttostr(uid),Socket.RemoteAddress,IntToStr(Socket.RemotePort),ListBox2);
  Userliste.Broadcast('JOIN User'+inttostr(uid)+' ('+Socket.RemoteHost+':'+IntToStr(Socket.RemotePort)+')',Server);
  ListBox1.Items.Add('*** User Connected: User'+inttostr(uid)+' ('+Socket.RemoteHost+':'+IntToStr(Socket.RemotePort)+') ***');
  inc(uid);
  StatusBar1.Panels[1].Text := IntToStr(Userliste.Count);
end;

procedure TForm1.ServerClientDisconnect(Sender: TObject;
  Socket: TCustomWinSocket);
  var xname: string;
begin
  try
    xname := Userliste.GetUsernamebyid(Socket.RemoteAddress+':'+IntToStr(Socket.RemotePort));
    Userliste.Broadcast('QUIT '+xname+' ('+Socket.RemoteHost+':'+IntToStr(Socket.RemotePort)+')',Server);
    ListBox1.Items.Add('*** User Disconnected: '+xname+' ('+Socket.RemoteHost+':'+IntToStr(Socket.RemotePort)+') ***');
  finally
    Userliste.Deleteuser(Socket.RemoteAddress, IntToStr(Socket.RemotePort),ListBox2);
    StatusBar1.Panels[1].Text := IntToStr(Userliste.Count);
  end;
end;

procedure TForm1.ServerClientError(Sender: TObject; Socket: TCustomWinSocket;
  ErrorEvent: TErrorEvent; var ErrorCode: Integer);
begin
    ListBox1.Items.Add('*** ERROR: ('+IntToStr(ErrorCode)+') ***');
end;

procedure TForm1.ServerClientRead(Sender: TObject; Socket: TCustomWinSocket);
var sr,xu, meta: string;
begin
  xu := Userliste.GetUsernamebyid(Socket.RemoteAddress+':'+IntTostr(Socket.RemotePort));
  sr := Socket.ReceiveText;
  if ((sr[1] = '/') AND (sr[2] = 's') AND (sr[3] = 'a') AND (sr[4] = 'y')) then // der say befehl sendet text an alle user
  begin
    Userliste.BroadCast(xu+': '+Copy(sr,6,length(sr)-5),Server);
    ListBox1.Items.Add('*** '+xu+': '+Copy(sr,6,length(sr)-5)+' ***');
  end;
  if ((sr[1] = '/') AND (sr[2] = 'n') AND (sr[3] = 'a') AND (sr[4] = 'm') AND (sr[5] = 'e')) then // mit /name ändert man den namen
  begin
    meta := Userliste.ChangeNickName(xu,Copy(sr,7,length(sr)-6),Server,ListBox2);
    if (meta <&amp;gt; '') then
      Userliste.Sendtextto('INFO',Socket.RemoteAddress,IntToStr(Socket.RemotePort),meta,Server)
    else
      ListBox1.Items.Add('*** Namensänderung: '+xu+' =&amp;gt; '+Copy(sr,7,length(sr)-6)+' ***');
  end;

end;

end.
Fehlende Funktionen:
- Senden von Dateien
- Senden von Text an bestimmte User
- Abrufen der Userliste vom Client
- die Popupmenucommands (kick, ban, info, sendmsg, sendfile)

*** Bisher hab ich noch nicht alle funktionen eingebaut, aber das sollte bald folgen.


Onlineupdate:
Diese Funktion ermöglicht es ohne Probleme bei wechselnder IP dem Clienten den Server zu finden
Sobald der Server ein Onlineupdate macht wird mit hilfe einer php datei die ip gespeichert.
Der Client hat ebenfalls einen Updatebutton und holt von der phpdatei die ipaddresse, somit
kann der Client ohne austauschen der IP über telefon/voicechat oder anderer chattools auf den Server connecten.

In der Datenbank hab ich eine Tabelle angelegt mit den werten:
- id: int(11)
- ip: varchar(255)

Leider wird der php code durch das Forum verpfuscht von daher hab ich das ganze als zip angehängt.
Der Server liegt immer auf id=1 die anderen sind wenn wer versucht die seite zu öffnen ohne korrekten $action-wert.
Das mit dem Onlineupdate kann aber jeder handhaben wie er will einfach code anpassen, fertig.



Probleme:
Momentan hab ich ein Problem damit wenn mehrere Clients gleichzeitig disconnecten, da ja sobald einer disconnected
an alle eine nachricht geschickt wird. wenn nun user1 kurz vor user2 rausgeht dann bekommt user2 "normalerweise" noch die
nachricht von user1 das er disconnected ist. und da der Client das nicht mehr empfangen kann da er ja zum selben augenblick
raus ist bekomm ich eine Fehlermeldung bzw stürzt sogar das Programm ab. :/ Mehrere Clients wie zum bsp Clone des angehängten
Client-Programms (welches nicht von mir ist habs in nem Tutorial gefunden) was ich ein wenig umgebaut hab und damit meinen
server teste. Brauchte erstmal nur ein kleines Client-Programm zum testen.

Bis auf die "Fehlenden Funktionen" und das "Problem" ist das ganze system funktionsfähig.
Man kann mit mehreren Clients connecten die clienten können schreiben der server kann schreiben und man kann den namen ändern.
und die nachricht wird mit dem namen angezeigt und nicht mit der "IP", "IPort" oder "Client".
Am Anfang bekommt auch jeder user einen namen zugewiesen "User+uid" also "User1" und steigend.

Ich werde den Sourcecode und die dateien auf dem aktuellsten stand halten wenn ich weitere Funktionen fertig habe.
Angehängte Dateien
Dateityp: zip chat_194.zip (18,3 KB, 29x aufgerufen)
Dateityp: zip pkontakt1_205.zip (15,0 KB, 25x aufgerufen)
Dateityp: zip php-files_528.zip (605 Bytes, 23x aufgerufen)
  Mit Zitat antworten Zitat
taaktaak

Registriert seit: 25. Okt 2007
Ort: Radbruch
1.990 Beiträge
 
Delphi 7 Professional
 
#2

Re: Chatserver mit TServerSocket

  Alt 3. Apr 2010, 11:24
Moin, Moin.

Obwohl ich schon so einige Jahre programmiere, ist gerade dieses Thema absolutes Neuland für mich. Da ich in meinen rzDelphiGuide aber einen Datenaustausch zwischen verschiedenen Nutzern einbauen möchte ist das alles recht interessant für mich. Aufgrund mangelnder Zeit würde ich allerdings ausnahmsweise eine (fast) fertige Lösung einbauen wollen. Nun schreibst du zwar dass ein Dateitransfer derzeit nicht möglich ist, ich deute deine Formulierung allerdings so, dass diese Funktionalität vorgesehen ist - ist das richtig?

Zunächst eine ganz naive Frage, die meine Unkenntniss nur zu deutlich macht: Wie findet denn das Programm in Stadt A die Programme, die gerade in Stadt B und C aktiv sind?
Ralph
  Mit Zitat antworten Zitat
Capa

Registriert seit: 26. Okt 2003
102 Beiträge
 
RAD-Studio 2010 Arc
 
#3

Re: Chatserver mit TServerSocket

  Alt 3. Apr 2010, 11:31
ähm also zur frage des dateitransfers ja das soll noch hinzukommen siehe "Fehlende Funktionen"
ein anfang ist ja schon drin zum thema dateitransfer aber auch nur von server zu client
im mom weiß ich noch nicht wie ich eine Client->Client sendung machen kann.

allerdings weiß ich nciht was du mit deiner frage
Zitat:
Zunächst eine ganz naive Frage, die meine Unkenntniss nur zu deutlich macht: Wie findet denn das Programm in Stadt A die Programme, die gerade in Stadt B und C aktiv sind?
genau aussagen willst, geht es dir um die allgemeine funktionalität des internets (so würde ich die frage deuten) oder willst du damit was anderes aussagen?

EDIT: Hab mir dein rzDelphiGuide mal runtergeladen, also wenn das alles so funktioniert wie es da aufgelistet ist muss ich sagen respekt,
du hast da aber sicher ne ganze menge zeit reingesteckt oder ?
Ich werde demnächst erst dein tool befragen und dann google ^^ !

Mfg Capa
  Mit Zitat antworten Zitat
taaktaak

Registriert seit: 25. Okt 2007
Ort: Radbruch
1.990 Beiträge
 
Delphi 7 Professional
 
#4

Re: Chatserver mit TServerSocket

  Alt 3. Apr 2010, 14:55
Hallo Capa,

dann lass mich meine Frage etwas umschreiben: Die Benutzer meines rzDelphiGuide sollen Themen-Texte austauschen können. Das stelle ich mir so vor, dass jeder Anwender ausgewählte Themen zum Austausch "freigibt" indem er den Thementitel in eine Liste einfügt und optional eine kurze Beschreibung erstellt. Andere Anwender sollen diese Liste (und die Beschreibung) einsehen können und, wenn das Thema für sie von Interesse ist, den Themen-Text in ihre Datenbank integrieren können - soweit der Grundgedanke. Nun frage ich mich, wie das technisch zu realisieren ist: Anwender X hat in Hamburg den rzDelphiGuide gestartet und einige Themen freigegeben. Wie findet nun Anwender Y, der in Berlin ebenfalls mit dem DelphiGuide arbeitet, den Anwender X in Hamburg um dessen "Angebotsliste" laden und ansehen zu können?

Hmm, ist das jetzt verständlicher? Wie gesagt, mir ist dieses Gebiet völlig fremd, daher habe ich zwar eine Zielvorstellung, aber absolut keinen Ansatz wie das funktionieren könnte...

zum rzDelphiGuide:

Deine Erwartung wird hoffentlich nicht enttäuscht! Die mitgelieferten Daten sind größtenteils nicht ernstzunehmende "Spieldaten" die einen Eindruck vermitteln sollen, wie das Programm mit einem etwas umfangreicheren Datenbestand arbeitet - das "googeln" können und sollen sie nicht ersetzen. Obwohl die letzte Aktualisierung nun schon eine ganze Weile zurück liegt, arbeite ich intensiv an dem Programm. In den letzten Monaten sind so schon wieder fast 100 Optimierungen eingeflossen und leider auch schlimme Fehler beseitigt worden. In einigen Wochen wird es sicherlich eine aktuelle Version geben. Tja, ich stecke doch eine ganze Menge Zeit hinein, bei etwa 1500 Stunden habe ich aber aufgehört zu zählen.
Ralph
  Mit Zitat antworten Zitat
Capa

Registriert seit: 26. Okt 2003
102 Beiträge
 
RAD-Studio 2010 Arc
 
#5

Re: Chatserver mit TServerSocket

  Alt 3. Apr 2010, 15:13
Also was deine Frage angeht wo die leute sind ist ja im Internet scheiss egal du brauchst ja nur die
addresse des Users in dem Fall die IP, das ist wie ne telefonnummer du rufst diese nummer an und
im Normalfall kommt das gespräch da an wo du hinwolltest.

Und was deine Idee angeht was du mit deinem Programm vorhast dafür wäre ein fester server nicht schlecht.

Solltest du dich wirklich weiter mit dem Thema Netzwerk und internet beschäftigen wollen solltest du dir
als erstes mal bücher/ebooks/websiten/etc zum thema TCP/IP anschauen. Damit du erstmal weißt worum es da überhaupt geht.
Wenn ich ehrlich bin kann ich mir garnciht vorstellen das jemand schon so lange delphi programmiert und keinen
Plan vom internet haben soll.
Ich hoffe das ist kein verspäteter Aprilscherz.
  Mit Zitat antworten Zitat
taaktaak

Registriert seit: 25. Okt 2007
Ort: Radbruch
1.990 Beiträge
 
Delphi 7 Professional
 
#6

Re: Chatserver mit TServerSocket

  Alt 3. Apr 2010, 15:25
Hihi, nee, kein April-Scherz! Hast du in der Hilfe von rzDelphiGuide meinen "programmiertechnischen Lebenslauf" gelesen, oder woraus schließt du, dass ich schon längere Zeit programmiere? Na, egal, stimmt schon. Habe mich immer vor einigen Dingen "gedrückt"; wenn es um Netzwerk, Router etc. geht, dann muss immer unser Sohn dem Papa helfen

Ok, die IP ist die Computer-Adresse, ob der Computer im Nebenraum steht, oder in Honululu, das ist egal. Aber ist das nicht der springende Punbkt? Die IP wird doch aber immer neu vergeben, wenn sich ein "normaler" Anwender mit dem Internet verbindet. Daher (denke ich) kann doch diese IP eben nicht unmittelbar als Adresse verwendet werden. Hmm...

Wenn ich einen Server miete - der hat dann immer die gleiche IP (oder???) dann könnten sich alle Anwender mit diesem zentralen Server verbinden. Aber, Hand auf Herz, das kostet doch Geld? Und vermutlich gar nicht mal so wenig?
Ralph
  Mit Zitat antworten Zitat
Benutzerbild von sx2008
sx2008

Registriert seit: 15. Feb 2008
Ort: Baden-Württemberg
2.332 Beiträge
 
Delphi 2007 Professional
 
#7

Re: Chatserver mit TServerSocket

  Alt 3. Apr 2010, 17:01
Zitat von Capa:
Mag sein das es für einige nicht die beste art ist einige sachen zu lösen aber ich bin auch für vorschläge offen
Jupp, da sind einige Sachen, die nicht so gut sind, aber das lässt sich ja ändern.
1.) Der Record TUserdata sollte in eine Klasse umgewandelt werden.
Damit würde Userid zu einer Funktion oder einem Property.
UserIP und UserPort sind ja schon vorhanden, also muss die Kombination aus beiden berechnet werden
Als Bonus würde ich noch LoginDateTime hinzubringen.
2.) Speicherung der Liste von TUserdata-Objekten.
Delphi-Quellcode:
TUserlist = class
  // vorher
// Userdaten: array[1..250] of TUserdata;
  // nachher
  FUserdaten: TObjectList;
Damit ist die Anzahl der User praktisch unbegrenzt. procedure TUserlist.Clear wird überflüssig.
3.) der Parameter mylist:TListBox gehört nicht in die Klasse TUserlist.
Damit wird nur eine Komponente der Benutzeroberfläche mit der tieferliegenden Klasse verquickt.
In function TUserlist.ChangeNickName könnte man z.B. eine Exception auslösen, wenn der neue Nickname schon vergeben ist.
  Mit Zitat antworten Zitat
Capa

Registriert seit: 26. Okt 2003
102 Beiträge
 
RAD-Studio 2010 Arc
 
#8

Re: Chatserver mit TServerSocket

  Alt 3. Apr 2010, 19:12
Warum sollte ich eine Exception auslösen wenn der Username schon vergeben ist ? dafür hab ich doch folgenden Code

zu 3tens:
Delphi-Quellcode:
function TUserlist.ChangeNickName(oldname,newname: string; Socket: TServerSocket; mylist: TListbox): string;
  var a,b,c: integer;
begin
  b := 0;
  for a := 1 to length(Userdaten) - 1 do
  begin
    if (Userdaten[a].Username = oldname) then
      c := a;
    if (Userdaten[a].Username = newname) then // wenn der name vergeben ist dann höre auf sagt er hier
    begin
      Result := '*** Name bereits vergeben! ***'; // und test's haben bewiesen das es so auch funktioniert
      b := 1;
      Exit; // und das sogar ohne Exception
    end;
  end;
  if (b = 0) then
  begin
    for a := 0 to mylist.Count - 1 do
    begin
      if (mylist.Items[a] = oldname) then
        mylist.Items[a] := newname;
    end;
    Userdaten[c].Username := newname;
    Broadcast('Namechange: '+oldname+' => '+newname,Socket);
    Result := '';
  end;
end;
welche erst nachschaut ob ein name schon vergeben ist und dann erst den namen ändert, oder hab ich da was falsch verstanden ?
ebenso werd ich die sache wo man die listbox angeben muss(bisher) demnächst noch ne überladene version ohne listbox hinzufügen
damit man auch wenn man keine listbox hat das ganze nutzen kann.

zu 2tens:
mit listen hab ich davor schon versucht zu arbeiten :/ nachdem ich jede menge exceptions bekommen hab durch
den normalen betrieb hab ichs aufgegeben und bin zu meiner version übergegangen ^^ die ich wenn ich ehrlich bin
irgendwie lieber mag ^^

zu 1tens:
mhh du meinst also ich brauch das mit der id nicht und sollte lieber logindatum mit speichern pro user.
das müsste ich ne menge abändern ^^

Achja hätte den auch wer ne idee zum dem Problem was ich geschildert hab ?




@ taaktaak
ein server kostet geld das ist richtig, ob viel oder wenig sei dahingestellt, allerdings was die wechselnden ip's angeht
dafür hab ich ja in meinem chatprogramm das "Onlineupdate" eingebaut, der server tut auf einer php seite einfach eine ip hinterlegen
die dann vom clienten abgefragt wird und schon weiß der client wo sich der server befindet.
und nen kleinen webspace bekommst auch heute noch geschenkt.


EDIT:
Wobei ich gestehen muss das beim Usernamen noch die möglichtkeit der nutzung von leerzeichen
besteht welche ich auch noch vor hatte zu eliminieren.
  Mit Zitat antworten Zitat
taaktaak

Registriert seit: 25. Okt 2007
Ort: Radbruch
1.990 Beiträge
 
Delphi 7 Professional
 
#9

Re: Chatserver mit TServerSocket

  Alt 3. Apr 2010, 19:45
Aha, dann speichert die php-Seite also nur die aktuellen IP's der Anwender die sich dort quasi anmelden. Das bedeutet aber, dass im Programm die Adresse der php-Seite fest hinterlegt sein muss, oder? Die eigentliche Kommunikation erfolgt dann direkt zwischen den einzelnen Anwendern - interessant!

Habe ich das jetzt richtig verstanden?
Vielen Dank für die Erläuterungen
Ralph
  Mit Zitat antworten Zitat
Capa

Registriert seit: 26. Okt 2003
102 Beiträge
 
RAD-Studio 2010 Arc
 
#10

Re: Chatserver mit TServerSocket

  Alt 3. Apr 2010, 20:14
nicht die clienten hinterlegen die ip sondern nur der server da die
clienten ja die ip vom server benötigen um sich zu verbinden.

Und ja die seite muss fest einprogrammiert sein oder aber man arbeitet
mit ini/xml dateien die möglichkeiten sind da weit offen ^^
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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:39 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