internal void SendData(ClientTelnetStateObject client, string data) { try { Socket clientSocket = client.ClientSocket; Log.Default.WriteLine(LogLevels.Debug, "Send data to client at " + ((IPEndPoint)clientSocket.RemoteEndPoint).Address + " : " + data); // Colorize or strip color string colorizedData = client.ColorAccepted ? AnsiHelpers.Colorize(data) : AnsiHelpers.StripColor(data); // Convert the string data to byte data using ASCII encoding. byte[] byteData = Encoding.ASCII.GetBytes(colorizedData); // Begin sending the data to the remote device. clientSocket.BeginSend(byteData, 0, byteData.Length, 0, SendCallback, client); } catch (ObjectDisposedException) { // If server status is stopping/stopped: ok // else, throw if (_status != ServerStatus.Stopping && _status != ServerStatus.Stopped && client.State != ClientStates.Disconnected) { throw; } } }
internal void CloseConnection(ClientTelnetStateObject client) { // Remove from 'client' collection _clients.Remove(client); // Socket clientSocket = client.ClientSocket; Log.Default.WriteLine(LogLevels.Info, "Client at " + ((IPEndPoint)clientSocket.RemoteEndPoint).Address + " has disconnected"); // Close socket clientSocket.Shutdown(SocketShutdown.Both); clientSocket.Close(); ClientDisconnected?.Invoke(client); }
internal void SendData(ClientTelnetStateObject client, byte[] byteData) { try { Socket clientSocket = client.ClientSocket; Log.Default.WriteLine(LogLevels.Debug, "Send data to client at " + ((IPEndPoint)clientSocket.RemoteEndPoint).Address + " : " + ByteArrayToString(byteData, byteData.Length)); // Begin sending the data to the remote device. clientSocket.BeginSend(byteData, 0, byteData.Length, 0, SendCallback, client); } catch (ObjectDisposedException) { // If server status is stopping/stopped: ok // else, throw if (_status != ServerStatus.Stopping && _status != ServerStatus.Stopped && client.State != ClientStates.Disconnected) { throw; } } }
private void SendCallback(IAsyncResult ar) { try { // Retrieve the socket from the state object. ClientTelnetStateObject client = (ClientTelnetStateObject)ar.AsyncState; Socket clientSocket = client.ClientSocket; // Complete sending the data to the remote device. int bytesSent = clientSocket.EndSend(ar); Log.Default.WriteLine(LogLevels.Debug, "Sent " + bytesSent + " bytes to client at " + ((IPEndPoint)clientSocket.RemoteEndPoint).Address); } catch (ObjectDisposedException) { // If server status is stopping/stopped: ok // else, throw if (_status != ServerStatus.Stopping && _status != ServerStatus.Stopped) { throw; } } }
private void AcceptCallback(IAsyncResult ar) { try { // Signal the ListenTask to continue. _listenEvent.Set(); // Get the socket that handles the client request. Socket listener = (Socket)ar.AsyncState; Socket clientSocket = listener.EndAccept(ar); Log.Default.WriteLine(LogLevels.Debug, "Client connected from " + ((IPEndPoint)clientSocket.RemoteEndPoint).Address); // Create the state object. ClientTelnetStateObject client = new ClientTelnetStateObject(this) { ClientSocket = clientSocket, }; _clients.Add(client); // TODO: NewClientConnected will be called once protocol handshake is done // client.State = ClientStates.Connected; NewClientConnected?.Invoke(client); // clientSocket.BeginReceive(client.Buffer, 0, ClientTelnetStateObject.BufferSize, 0, ReadCallback, client); } catch (ObjectDisposedException) { // If server status is stopping/stopped: ok // else, throw if (_status != ServerStatus.Stopping && _status != ServerStatus.Stopped) { throw; } } }
private void ReadCallback(IAsyncResult ar) { // Retrieve the state object and the handler socket // from the asynchronous state object. ClientTelnetStateObject client = (ClientTelnetStateObject)ar.AsyncState; try { Socket clientSocket = client.ClientSocket; // Read data from the client socket. int bytesRead = clientSocket.EndReceive(ar); Log.Default.WriteLine(LogLevels.Debug, "Received " + bytesRead + " bytes from client at " + ((IPEndPoint)clientSocket.RemoteEndPoint).Address); if (bytesRead == 0) { // Something goes wrong, close connection CloseConnection(client); } else { // // Putty handshake is // //FF FB 1F window size // //FF FB 20 terminal speed // //FF FB 18 terminal type // //FF FB 27 Telnet Environment Option // //FF FD 01 echo // //FF FB 03 suppress go ahead // //FF FD 03 suppress go ahead // //FF FE 01 received after echo on //Log.Default.WriteLine(LogLevels.Debug, "Data received from client at " + ((IPEndPoint)clientSocket.RemoteEndPoint).Address + " : " + ByteArrayToString(client.Buffer, bytesRead)); // Remove protocol character if (bytesRead % 3 == 0 && client.Buffer[0] == 0xFF)// && client.Buffer[1] == 0xFB) { Log.Default.WriteLine(LogLevels.Info, "Protocol received from client at " + ((IPEndPoint)clientSocket.RemoteEndPoint).Address + " : " + ByteArrayToString(client.Buffer, bytesRead)); } else if (client.State == ClientStates.Connected) { string dataReceived = Encoding.ASCII.GetString(client.Buffer, 0, bytesRead); Log.Default.WriteLine(LogLevels.Debug, "Data received from client at " + ((IPEndPoint)clientSocket.RemoteEndPoint).Address + " : " + dataReceived); // If data ends with CRLF, remove CRLF and consider command as complete bool commandComplete = false; if (dataReceived.EndsWith("\n") || dataReceived.EndsWith("\r")) { commandComplete = true; dataReceived = dataReceived.TrimEnd('\r', '\n'); } // Remove non-ascii char dataReceived = AsciiRegEx.Replace(dataReceived, string.Empty); // Append data in command client.Command.Append(dataReceived); // Command is complete, send it to command processor and start a new one if (commandComplete) { // Get command string command = client.Command.ToString(); Log.Default.WriteLine(LogLevels.Info, "Command received from client at " + ((IPEndPoint)clientSocket.RemoteEndPoint).Address + " : " + command); // Reset command client.Command.Clear(); // Process command client.OnDataReceived(command); } } // TODO: other states ? // Continue reading clientSocket.BeginReceive(client.Buffer, 0, ClientTelnetStateObject.BufferSize, 0, ReadCallback, client); } } catch (ObjectDisposedException) { // If server status is stopping/stopped: ok // else, throw if (_status != ServerStatus.Stopping && _status != ServerStatus.Stopped && client.State != ClientStates.Disconnected) { throw; } } }