|
Antwort |
Registriert seit: 26. Okt 2003 102 Beiträge RAD-Studio 2010 Arc |
#1
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:
Fehlende Funktionen:
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 &gt;= 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 &gt;= 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 <&gt; '') then Userliste.Sendtextto('INFO',Socket.RemoteAddress,IntToStr(Socket.RemotePort),meta,Server) else ListBox1.Items.Add('*** Namensänderung: '+xu+' =&gt; '+Copy(sr,7,length(sr)-6)+' ***'); end; end; end. - 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. |
Zitat |
Registriert seit: 25. Okt 2007 Ort: Radbruch 1.990 Beiträge Delphi 7 Professional |
#2
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
|
Zitat |
Registriert seit: 26. Okt 2003 102 Beiträge RAD-Studio 2010 Arc |
#3
ä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?
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 |
Zitat |
Registriert seit: 25. Okt 2007 Ort: Radbruch 1.990 Beiträge Delphi 7 Professional |
#4
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
|
Zitat |
Registriert seit: 26. Okt 2003 102 Beiträge RAD-Studio 2010 Arc |
#5
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. |
Zitat |
Registriert seit: 25. Okt 2007 Ort: Radbruch 1.990 Beiträge Delphi 7 Professional |
#6
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
|
Zitat |
Registriert seit: 16. Feb 2008 Ort: Baden-Württemberg 2.332 Beiträge Delphi 2007 Professional |
#7
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
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:
Damit ist die Anzahl der User praktisch unbegrenzt. procedure TUserlist.Clear wird überflüssig.
TUserlist = class
// vorher // Userdaten: array[1..250] of TUserdata; // nachher FUserdaten: TObjectList; 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. |
Zitat |
Registriert seit: 26. Okt 2003 102 Beiträge RAD-Studio 2010 Arc |
#8
Warum sollte ich eine Exception auslösen wenn der Username schon vergeben ist ? dafür hab ich doch folgenden Code
zu 3tens:
Delphi-Quellcode:
welche erst nachschaut ob ein name schon vergeben ist und dann erst den namen ändert, oder hab ich da was falsch verstanden ?
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; 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. |
Zitat |
Registriert seit: 25. Okt 2007 Ort: Radbruch 1.990 Beiträge Delphi 7 Professional |
#9
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
|
Zitat |
Registriert seit: 26. Okt 2003 102 Beiträge RAD-Studio 2010 Arc |
#10
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 ^^ |
Zitat |
Themen-Optionen | Thema durchsuchen |
Ansicht | |
ForumregelnEs 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
|
|
Nützliche Links |
Heutige Beiträge |
Sitemap |
Suchen |
Code-Library |
Wer ist online |
Alle Foren als gelesen markieren |
LinkBack |
LinkBack URL |
About LinkBacks |