Moin!
Richtig, beim ClientConnect gibt es noch keine Kommunikation und der Client kann daher nur danach seinen Nick schicken. Daher musst du das nachträglich zuordnen. Erstmal aber nochwas zwischendurch: Die ListBox speichert nicht die Sockets - sie hält auch einen Verweis auf diese Instanzen. Der ServerSocket verwaltet und hält diese hauptsächlich. Daher kannst du z.B. auch weiterhin die Connections[] des ServerSockets durchgehen um den Nickname zu zu ordnen. Andere Möglichkeit: Du baust dir ein Objekt - besser eine kleine Klasse - die nix weiter enthält als 2 Variablen im Public Bereich:
Delphi-Quellcode:
TUserSocket = Class
Public
Socket : TCustomWinSocket;
NickName : String;
End;
Und wenn du nun bei der ListBox einfach anstatt dem Socket folgendes hinzufügst:
Delphi-Quellcode:
Procedure TForm1.ServerSocket1ClientConnect(Sender: TObject; Socket: TCustomWinSocket);
Var
lTemp : String;
lUser : TUserSocket;
Begin
Memo1.Lines.Add(timetostr(now)+' Neuer User betritt den Chat !');
edit10.text := 'User eingeloggt: ' + IntToStr(ServerSocket1.Socket.ActiveConnections);
lUser := TUserSocket.Create;
lUser.Socket := Socket;
lUser.NickName := ''; // noch unbekannt, sind ja im Connect...
lTemp := Socket.RemoteHost + ' ' + Socket.RemoteAddress;
ListBox1.Items.AddObject(lTemp, lUser);
End;
Somit haben wir es nun so, das wir nicht mehr direkt den Socket reinhängen sondern diese Instanz von TUserSocket die uns beide nötigen Informationen hält: Den Socket und den Nick. Nun fehlt noch die Zuordnung vom Nick:
Delphi-Quellcode:
// Diese Funktion geht nur durch die ListBox durch und sucht den TUserSocket zu dem übergebenen Socket
Function TForm1.FindUserSocket(ASocket : TCustomWinSocket): TUserSocket;
Var
i : Integer;
Begin
Result := Nil;
For i := 0 To ListBox1.Items.Count-1 Do
If ( TUserSocket(ListBox1.Items.Objects[i]).Socket = ASocket ) Then
Begin
Result := TUserSocket(ListBox1.Items.Objects[i]);
Break;
End;
End;
procedure TForm1.ServerSocket1ClientRead(Sender: TObject; Socket: TCustomWinSocket);
var
lUser : TUserSocket;
lText : string;
begin
lText := Socket.ReceiveText;
lUser := FindUserSocket( Socket );
If ( Assigned(lUser) ) Then
Begin
lText := xorstring(lText, '');
lUser.NickName := Copy(lText, 1, 6);
ShowMessage(lUser.NickName);
End;
End;
Nun enthält die TUserSocket in der ListBox auch den Nickname, wenn der denn ankommt.
Dadurch, das in der ListBox nun eine Instanz von TUserObject hängt die wir selber instanziiert haben, müssen wir uns um die Freigabe kümmern und natürlich die anderen Routinen abhändern.
Delphi-Quellcode:
Procedure TForm1.ServerSocket1ClientDisconnect(Sender: TObject; Socket: TCustomWinSocket);
Var
i : Integer;
lUser : TUserSocket;
Begin
// Socket ist eindeutig, daher haben wir durch das Connect schon diesen Socket auch in der ListBox.
// Also: ListBox1.Items.Objects[] durchgehen, schauen wo dieser übergebene Socket ist und dann den
// Eintrag löschen. Fertig!
Memo1.Lines.Add(timetostr(now)+' User verlässt den Chat !');
edit10.text := 'User eingeloggt: ' + IntToStr(ServerSocket1.Socket.ActiveConnections-1); // noch ist ActiveConnections nicht aktuell!
lUser := FindUserSocket( Socket );
If ( Assigned(lUser) ) Then
Begin
For i := 0 To ListBox1.Items.Count-1 Do
Begin
If ( ListBox1.Items.Objects[i] = lUser ) Then
Begin
ListBox1.Items.Delete(i);
Break;
End;
End;
lUser.Free;
End;
End;
Procedure TForm1.Button1Click(Sender: TObject);
Var
lUser : TUserSocket;
Begin
// wenn ein Eintrag ausgewählt ist...
If ( ListBox1.ItemIndex > -1 ) Then
Begin
// dann den mit AddObject() hinzugefügten TUserSocket mal rausholen
lUser := ListBox1.Items.Objects[ ListBox1.ItemIndex ] As TUserSocket;
ShowMessage(lUser.NickName + ' wurde gekickt');
// ... und dann einfach den Socket schliessen
lUser.Socket.Close;
End;
End;
Zu den ClientSocket/ServerSocket als Chat mit Nicks, Channels, etc siehe für Ideen und Hinweise auch den (bisher noch unkommentierten) Code von mir an:
Chat Beispiel.
MfG
Muetze1