unit ServerMainFormManager;
interface
uses
...
type
TServerMainFormManager =
class
private
m_mainForm : TServerMainForm;
m_socketListen : Socket;
m_socketAccept : Socket;
m_Backlog : integer;
m_WorkerCallback : AsyncCallback;
Logger : ILog;
m_CommandCompleteEvent : TCommandCompleteEventHandler;
m_currentCommandString :
string;
m_currentCommandStringLocked : boolean;
m_SendCommandAnswer :
string;
procedure acceptCallback(asyncResult : IAsyncResult);
procedure onDataReceived(asyncResult : IAsyncResult);
procedure waitForData(pSocket : Socket);
procedure processData(newChar :
string);
//Events vom Formular
procedure ButtonStartClicked(Sender: TObject; Args: EventArgs);
procedure ButtonSendClicked(Sender: TObject; Args: EventArgs);
procedure ButtonStopClicked(Sender: TObject; Args: EventArgs);
//Events
procedure removeCommandCompleteEvent(event : TCommandCompleteEventHandler);
procedure addCommandCompleteEvent(event : TCommandCompleteEventHandler);
function getCurrentCommandString:
string;
public
property ReceivedCommandString :
string read getCurrentCommandString;
property CommandCompleteEventHandler : TCommandCompleteEventHandler add addCommandCompleteEvent remove removeCommandCompleteEvent;
constructor Create;
procedure start();
procedure SendCommandAnswer(answer:
string);
end;
implementation
{$REGION 'Constructor'}
constructor TServerMainFormManager.Create;
begin
inherited Create;
Logger := LogManager.GetLogger('
TServerMainFormManager');
XmlConfigurator.Configure(FileInfo.Create('
LogConfig.xml'));
m_mainForm := TServerMainForm.Create();
Include(m_mainForm.ButtonStart.Click,ButtonStartClicked);
Include(m_mainForm.ButtonSend.Click,ButtonSendClicked);
Include(m_mainForm.ButtonStopServer.Click,ButtonStopClicked);
m_Backlog := 1;
end;
function TServerMainFormManager.getCurrentCommandString:
string;
begin
//Zuerst den String Locken
Result := m_currentCommandString;
end;
{$ENDREGION}
{$REGION 'Mainform Events'}
procedure TServerMainFormManager.ButtonStartClicked(Sender: TObject;Args: EventArgs);
var serverPort : integer;
begin
try
//einen neuen socket erzeugen
m_socketListen := Socket.Create(AddressFamily.InterNetwork,
SocketType.Stream,
ProtocolType.Tcp);
Logger.Debug('
New Socket created, Port: '+m_mainForm.NumericUpDownPort.Value.ToString());
//Port auslesen
serverPort := Convert.ToInt32(m_mainForm.NumericUpDownPort.Value);
m_socketListen.Bind(IPEndPoint.Create(IPAddress.Any,serverPort));
Logger.Debug('
Socket Bind');
//Das Listening starten
m_socketListen.Listen(m_Backlog);
Logger.Debug('
Socket listening');
//Rückruf für jeden Clienten
m_socketListen.BeginAccept(acceptCallback,
nil);
Logger.Debug('
Socket waits for Clients');
if (m_socketListen.Connected)
then
Logger.Debug('
Connected');
m_mainForm.ButtonStart.Enabled := false;
m_mainForm.ButtonStoPServer.Enabled := true;
m_mainForm.NumericUpDownPort.Enabled := false;
except
on E:SocketException
do begin
Logger.Error(E.
Message);
end;
end;
end;
procedure TServerMainFormManager.ButtonStopClicked(Sender: TObject;
Args: EventArgs);
begin
try
if assigned(m_socketAccept)
and (m_socketAccept.Connected)
then
m_socketAccept.Shutdown(SocketShutdown.Both);
if assigned(m_socketListen)
and m_socketListen.Connected
then begin
m_socketListen.Shutdown(SocketShutdown.Both);
end;
m_socketListen.Close();
m_mainForm.ButtonStart.Enabled := true;
m_mainForm.ButtonStoPServer.Enabled := false;
m_mainForm.NumericUpDownPort.Enabled := true;
except
on E:SocketException
do begin
Logger.Error(E.
Message);
end;
end;
end;
procedure TServerMainFormManager.ButtonSendClicked(Sender: TObject;Args: EventArgs);
var objData : TObject;
byteData :
array of byte;
begin
try
//Sende Daten an den Client
Logger.Debug('
Send Data to Client...');
objData := m_mainForm.TextBoxSend.Text;
byteData := System.Text.Encoding.ASCII.GetBytes(objData.ToString());
m_socketAccept.Send(byteData);
Logger.Debug('
Data send to Client successful');
except
on E:
Exception do
Logger.Error(E.
Message);
end;
end;
{$ENDREGION}
{$REGION 'Private Functions'}
procedure TServerMainFormManager.removeCommandCompleteEvent(event: TCommandCompleteEventHandler);
begin
m_CommandCompleteEvent := TCommandCompleteEventHandler(Delegate.Remove(@m_CommandCompleteEvent,@event));
end;
procedure TServerMainFormManager.addCommandCompleteEvent(event : TCommandCompleteEventHandler);
begin
m_CommandCompleteEvent := TCommandCompleteEventHandler(Delegate.Combine(@m_CommandCompleteEvent,@event));
end;
{$ENDREGION}
procedure TServerMainFormManager.start;
begin
m_mainForm.ShowDialog();
end;
procedure TServerMainFormManager.acceptCallback(asyncResult: IAsyncResult);
begin
try
//Callback
Logger.Debug('
Callback');
m_socketAccept := m_socketListen.EndAccept(asyncResult);
waitForData(m_socketAccept);
except
on E:SocketException
do
Logger.Error(E.
Message);
end;
end;
procedure TServerMainFormManager.waitForData(pSocket: Socket);
var socPkt : TSocketPacket;
begin
try
if not assigned(m_WorkerCallback)
then begin
m_WorkerCallback := ondataReceived;
end;
socPkt := TSocketPacket.Create();
socPkt.socket := pSocket;
//now start to listen for data
Logger.Debug('
Listening for any data...');
pSocket.BeginReceive(socPkt.dataBuffer,
0,
length(socPkt.databuffer),
SocketFlags.None,
m_WorkerCallback,
socPkt);
except
on E:
Exception do
Logger.Error(E.
Message);
end;
end;
procedure TServerMainFormManager.onDataReceived(asyncResult: IAsyncResult);
var theSockID : TSocketPacket;
iRx, charLen : integer;
dec : Decoder;
chars :
array of char;
szData :
string;
begin
try
theSockID := TSocketPacket(asyncResult.AsyncState);
//Empfange die Daten
Logger.Debug('
Receive Data');
iRx := theSockID.socket.EndReceive(asyncResult);
SetLength(chars,iRx+1);
dec := System.Text.Encoding.ASCII.GetDecoder();
charLen :=
dec.GetChars(theSockID.dataBuffer, 0, iRx, chars, 0);
szData :=
string(chars);
m_mainForm.TextBoxReceived.Text := m_mainForm.TextBoxReceived.Text + szData;
//Die Daten werden verarbeitet
processData(szData);
Logger.Debug(m_currentCommandString);
waitForData(m_socketAccept);
except
on E:ObjectDisposedException
do
Logger.Debug('
OnDataReceived: Socket has been closed');
on E: SocketException
do
Logger.Error(E.
Message);
end;
end;
procedure TServerMainFormManager.processData(newChar:
string);
begin
...
end;
procedure TServerMainFormManager.SendCommandAnswer(answer:
string);
begin
...
end;
end.