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:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176: 177: 178: 179: 180: 181: 182: 183: 184: 185: 186: 187: 188: 189: 190: 191: 192: 193: 194: 195: 196: 197: 198: 199: 200: 201: 202: 203: 204: 205: 206: 207: 208: 209: 210: 211: 212: 213: 214: 215: 216: 217: 218: 219: 220: 221: 222: 223: 224: 225: 226: 227: 228: 229: 230: 231: 232: 233: 234: 235: 236: 237: 238: 239: 240: 241: 242: 243: 244: 245: 246: 247: 248: 249: 250: 251: 252: 253: 254: 255: 256: 257: 258: 259: 260: 261: 262: 263: 264: 265: 266: 267: 268: 269: 270: 271: 272: 273: 274: 275: 276: 277: 278: 279: 280: 281: 282: 283: 284: 285: 286: 287: 288: 289: 290: 291: 292: 293: 294: 295: 296: 297: 298: 299: 300: 301: 302: 303: 304: 305: 306: 307: 308: 309: 310: 311: 312: 313: 314: 315: 316: 317:
| 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);
procedure ButtonStartClicked(Sender: TObject; Args: EventArgs); procedure ButtonSendClicked(Sender: TObject; Args: EventArgs); procedure ButtonStopClicked(Sender: TObject; Args: EventArgs);
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
Result := m_currentCommandString;
end;
{$ENDREGION}
{$REGION 'Mainform Events'} procedure TServerMainFormManager.ButtonStartClicked(Sender: TObject;Args: EventArgs); var serverPort : integer; begin
try
m_socketListen := Socket.Create(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
Logger.Debug('New Socket created, Port: '+m_mainForm.NumericUpDownPort.Value.ToString());
serverPort := Convert.ToInt32(m_mainForm.NumericUpDownPort.Value); m_socketListen.Bind(IPEndPoint.Create(IPAddress.Any,serverPort)); Logger.Debug('Socket Bind');
m_socketListen.Listen(m_Backlog); Logger.Debug('Socket listening');
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
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
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;
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);
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;
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. |
danke,
winx
ps: hab das thema auch hier gepostet:
www.delphipraxis.net...st559848.html#559848Moderiert von Christian S.: Topic aus .NET verschoben am Mi 07.06.2006 um 12:56