|
Registriert seit: 14. Jun 2005 265 Beiträge |
#1
Guten Morgen,
ich hab mir einen kleinen Server aufgesetzt, der asynchron Daten von Clients empfangen kann. Nur hab ich jetzt zwei Probleme: 1. Wie kann ich den einmal gestarteten Server wieder stoppen??? bekomm bei meinem versuch (ButtonStopClick) immer die eine InvalidOperationException "AcceptCallback" 2. Wie bekommt mein Server mit, wenn sich ein angemeldeter Client mit ClientSocket.Shutdown(SocketShutdown.Both); abmeldet?? Der Code meines Servers sieht so aus:
Delphi-Quellcode:
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. |
![]() |
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 |
Gehe zu... |
LinkBack |
![]() |
![]() |