unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Dialogs, ScktComp, StdCtrls;
const
// Port, an dem der ServerSocket auf Clients wartet
SERVER_PORT = 12345;
type
// Verbindungszustände des Clients (für die Button-Steuerung)
TMyConState = (
mcsOffline,
// nicht verbunden
mcsPending,
// Verbindungsstatus ändert sich gerade
mcsOnline
// verbunden
);
TForm1 =
class(TForm)
server: TEdit;
nickname: TEdit;
log: TMemo;
btnconnect: TButton;
btndisconnect: TButton;
Clients: TListBox;
btnsend: TButton;
input: TEdit;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
Label4: TLabel;
ClientSocket1: TClientSocket;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure BtnConnectClick(Sender: TObject);
procedure BtnDisconnectClick(Sender: TObject);
procedure ClientSocket1Connect(Sender: TObject;
Socket: TCustomWinSocket);
procedure ClientSocket1Disconnect(Sender: TObject; Socket: TCustomWinSocket);
procedure ClientSocket1Error(Sender: TObject; Socket: TCustomWinSocket;
ErrorEvent: TErrorEvent;
var ErrorCode: Integer);
procedure BtnSendClick(Sender: TObject);
procedure InputKeyPress(Sender: TObject;
var Key: Char);
procedure ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);
private
FMyConState: TMyConState;
procedure SetConState(
const Value: TMyConState);
public
property ConnectionState: TMyConState
read FMyConState
write SetConState;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
// bei Programmstart ausführen
procedure TForm1.FormCreate(Sender: TObject);
begin
ClientSocket1.Port := SERVER_PORT;
// Port setzen
ConnectionState := mcsOffline;
// Buttons anpassen
end;
// neuer Verbindungsstatus -> GUI anpassen
procedure TForm1.SetConState(
const Value: TMyConState);
begin
FMyConState := Value;
// neuen Status speichern
// Buttons entsprechend de-/aktivieren
BtnConnect.Enabled := (Value = mcsOffline);
BtnDisconnect.Enabled := (Value = mcsOnline);
BtnSend.Enabled := (Value = mcsOnline);
end;
// bei Programmende ausführen
procedure TForm1.FormDestroy(Sender: TObject);
begin
BtnDisconnectClick(Self);
// auf jeden Fall abmelden
end;
// Verbindung zum Server aufnehmen
procedure TForm1.BtnConnectClick(Sender: TObject);
begin
ConnectionState := mcsPending;
// Buttons anpassen
ClientSocket1.Host := Server.Text;
// Serveradresse übernehmen
ClientSocket1.Open;
// Verbindung versuchen und warten, was passiert
// Verbindung OK: weiter bei ClientSocket1Connect(), sonst ClientSocket1Error()
end;
// Verbindung zum Server trennen
procedure TForm1.BtnDisconnectClick(Sender: TObject);
begin
ConnectionState := mcsPending;
// Buttons anpassen
if (ClientSocket1.Active)
then // noch verbunden?
ClientSocket1.Close
// dann trennen und warten, was passiert
// Trennung OK: weiter in ClientSocket1Disconnect(), sonst ClientSocket1Error()
else
ConnectionState := mcsOffline;
// sonst sind wir schon Offline
end;
// Verbindung zum Server ist aufgebaut und bereit zum Senden/Empfangen
procedure TForm1.ClientSocket1Connect(Sender: TObject; Socket: TCustomWinSocket);
begin
ConnectionState := mcsOnline;
// Buttons anpassen
Log.Clear;
// Protokollfenster löschen
Log.Lines.Add('
Verbunden mit: '+ClientSocket1.Socket.RemoteHost);
end;
// Verbindung zum Server (normal) getrennt
procedure TForm1.ClientSocket1Disconnect(Sender: TObject; Socket: TCustomWinSocket);
begin
ConnectionState := mcsOffline;
// Buttons anpassen
Clients.Clear;
// User-Liste leeren
Log.Lines.Add('
Verbindung getrennt.');
end;
// Es ist ein Fehler in der Verbindung aufgetreten; sicherheitshalber trennen
procedure TForm1.ClientSocket1Error(Sender: TObject; Socket: TCustomWinSocket;
ErrorEvent: TErrorEvent;
var ErrorCode: Integer);
begin
if (ClientSocket1.Active)
then // noch verbunden?
ClientSocket1.Close;
// ja, dann trennen
ConnectionState := mcsOffline;
// Buttons anpassen
Clients.Clear;
// User-Liste leeren
ErrorCode := 0;
// Fehler behandelt, keine Exception erzeugen
Log.Lines.Add('
Verbindungsfehler!');
end;
// Benutzernachricht senden ("reden")
procedure TForm1.BtnSendClick(Sender: TObject);
begin
ClientSocket1.Socket.SendText(Input.Text);
end;
// Eingabetaste im Textfeld -> senden und wieder alles auswählen
procedure TForm1.InputKeyPress(Sender: TObject;
var Key: Char);
begin
if (Key = #13)
then begin // Return/Enter gedrückt?
BtnSendClick(Self);
// dann Text senden
Input.SetFocus;
// Editfeld wieder auswählen
Input.SelectAll;
// und den ganzen Text markieren
end;
end;
// Daten vom Server empfangen
procedure TForm1.ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);
begin
Log.Lines.Add(Socket.ReceiveText);
// Daten lesen
end;
end.