/// <summary> /// Handles an incoming connection. /// If incoming connections are allowed, /// the client is added to the clients list /// and triggers the client connected event. /// Else, the connection blocked event is /// triggered. /// </summary> private void handleIncomingConnection(IAsyncResult result) { try { Socket oldSocket = (Socket)result.AsyncState; if (acceptIncomingConnections) { Socket newSocket = oldSocket.EndAccept(result); uint clientID = (uint)clients.Count + 1; Client client = new Client(clientID, (IPEndPoint)newSocket.RemoteEndPoint); clients.Add(newSocket, client); // Start negotiation sendBytesToSocket(newSocket, Negotiation.Do(Negotiation.Operations.Echo)); sendBytesToSocket(newSocket, Negotiation.Do(Negotiation.Operations.RemoteFlowControl)); sendBytesToSocket(newSocket, Negotiation.Will(Negotiation.Operations.Echo)); sendBytesToSocket(newSocket, Negotiation.Will(Negotiation.Operations.SuppressGoAhead)); sendBytesToSocket(newSocket, Negotiation.Will(Negotiation.Operations.BinaryTransmission)); sendBytesToSocket(newSocket, Negotiation.Do(Negotiation.Operations.NegotiateAboutWindowSize)); sendBytesToSocket(newSocket, Negotiation.Do(Negotiation.Operations.TerminalType)); client.resetReceivedData(); ClientConnected(client); serverSocket.BeginAccept(new AsyncCallback(handleIncomingConnection), serverSocket); } else { ConnectionBlocked((IPEndPoint)oldSocket.RemoteEndPoint); } } catch { } }
/// <summary> /// Receives and processes data from a socket. /// It triggers the message received event in /// case the client pressed the return key. /// </summary> private void receiveData(IAsyncResult result) { try { Socket clientSocket = (Socket)result.AsyncState; Client client = getClientBySocket(clientSocket); int bytesReceived = clientSocket.EndReceive(result); if (bytesReceived == 0) { closeSocket(clientSocket); ClientDisconnected(client); serverSocket.BeginAccept(new AsyncCallback(handleIncomingConnection), serverSocket); } else if (data[0] == (byte)Negotiation.Tokens.IAC) { // Negotiation int offset = 0; while (offset < bytesReceived) { Negotiation.HandleBinary(data, offset, client); Negotiation.HandleWindowSize(data, offset, client); if (Negotiation.ClientWillTerminalType(data, offset)) { sendBytesToSocket(clientSocket, Negotiation.AskForTerminalType()); } if (Negotiation.HandleTerminalType(data, offset, client)) { sendBytesToSocket(clientSocket, Negotiation.AskForTerminalType()); } while (++offset < bytesReceived) { if (data[offset] == (byte)Negotiation.Tokens.IAC) { break; } } } clientSocket.BeginReceive(data, 0, dataSize, SocketFlags.None, new AsyncCallback(receiveData), clientSocket); } else if (data[0] < 0xF0) { string receivedData = client.receivedData; client.lastActivity = DateTime.Now; // 0x2E = '.', 0x0D = carriage return, 0x0A = new line if ((data[0] == 0x2E && data[1] == 0x0D && receivedData.Length == 0) || (data[0] == 0x0D && data[1] == 0x0A) || data[0] == 0x0D || data[0] == 0x0A) { //sendMessageToSocket(clientSocket, "\u001B[1J\u001B[H"); MessageReceived(client, client.receivedData); client.resetReceivedData(); } else { // 0x08 => backspace character if (data[0] == 0x08) { if (receivedData.Length > 0) { client.removeLastCharacterReceived(); sendBytesToSocket(clientSocket, new byte[] { 0x08, 0x20, 0x08 }); } else { clientSocket.BeginReceive(data, 0, dataSize, SocketFlags.None, new AsyncCallback(receiveData), clientSocket); } } // 0x7F => delete character else if (data[0] == 0x7F) { clientSocket.BeginReceive(data, 0, dataSize, SocketFlags.None, new AsyncCallback(receiveData), clientSocket); } else if (data[0] < 0x20) { ControlCharReceived(client, data, bytesReceived); } else { client.appendReceivedData(Encoding.ASCII.GetString(data, 0, bytesReceived)); // Echo back the received character // if client is not writing any password if (client.inputMode != EInputMode.PasswordMode) { sendBytesToSocket(clientSocket, new byte[] { data[0] }); } // Echo back asterisks if client is // writing a password else { sendMessageToSocket(clientSocket, "*"); } clientSocket.BeginReceive(data, 0, dataSize, SocketFlags.None, new AsyncCallback(receiveData), clientSocket); } } } else { clientSocket.BeginReceive(data, 0, dataSize, SocketFlags.None, new AsyncCallback(receiveData), clientSocket); } } catch { } }