I've got the client/server working, the client is sending data to the server with no issues, and right now I just have a RichTextBox displaying the data received from the client.
What I would like to do is have the server display the data received in the RichTextBox, and then SendKeys the message to the active window (the server will be minimized to the system tray while this is happening).
CLIENT PORTION:
using System.Net;
using System.Net.Sockets;
private TcpClient client = new TcpClient();
private IPEndPoint serverEndPoint = new IPEndPoint(IPAddress.Parse("MyIP"), 8888);
public Console()
{
InitializeComponent();
client.Connect(serverEndPoint);
}
private void SendMessage(string msg)
{
NetworkStream clientStream = client.GetStream();
ASCIIEncoding encoder = new ASCIIEncoding();
byte[] buffer = encoder.GetBytes(msg);
clientStream.Write(buffer, 0, buffer.Length);
clientStream.Flush();
}
///...
private void button1_Click(object sender, EventArgs e)
{
SendMessage("T");
}
Now, all of that seems fine to me, as my server app is receiving the message just fine. My problem is on the server side. I can't seem to get the SendKeys function to work properly, so I've commented it out of my code snippet:
SERVER PORTION:
using System.Net;
using System.Net.Sockets;
using System.Threading;
private TcpListener tcpListener;
private Thread listenThread;
private int connectedClients = 0;
private delegate void WriteMessageDelegate(string msg);
public Form1()
{
InitializeComponent();
Server();
}
private void Server()
{
this.tcpListener = new TcpListener(IPAddress.Any, 8888);
this.listenThread = new Thread(new ThreadStart(ListenForClients));
this.listenThread.Start();
}
private void ListenForClients()
{
this.tcpListener.Start();
while (true)
{
TcpClient client = this.tcpListener.AcceptTcpClient();
connectedClients++;
lblNumberOfConnections.Text = connectedClients.ToString();
Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClientComm));
clientThread.Start(client);
}
}
private void HandleClientComm(object client)
{
TcpClient tcpClient = (TcpClient)client;
NetworkStream clientStream = tcpClient.GetStream();
byte[] message = new byte[4096];
int bytesRead;
while (true)
{
bytesRead = 0;
try
{
bytesRead = clientStream.Read(message, 0, 4096);
}
catch
{
break;
}
if (bytesRead == 0)
{
connectedClients--;
lblNumberOfConnections.Text = connectedClients.ToString();
break;
}
ASCIIEncoding encoder = new ASCIIEncoding();
//Write message in RichTextBox and send keystrokes to active window
string msg = encoder.GetString(message, 0, bytesRead);
WriteMessage(msg);
// SendKeys.Send(msg);
}
tcpClient.Close();
}
private void WriteMessage(string msg)
{
if (this.rtbServer.InvokeRequired)
{
WriteMessageDelegate d = new WriteMessageDelegate(WriteMessage);
this.rtbServer.Invoke(d, new object[] { msg });
}
else
{
this.rtbServer.AppendText(msg + Environment.NewLine);
}
As I said, it displays the data in the textbox just fine, but what I'd like to do as well (and the main purpose of this app) is to take the message received from the client, and add it to a SendKeys (or similar), and simulate those key presses in the active window. I just can't seem to figure out how to do that though...
Also, since I used SendMessage in my client app, and some of the keypresses I need to send to the active window contain modifiers, I just sent them as a text message to my server (ie. for the command CTRL-T, I literally sent the text "CTRL-T" to my server app), I was hoping I could do something along the lines of this:
SendKeys.Send("T");
)SendKeys.Send("{^T}");
)I don't have a problem assigning the events for commands with modifiers manually, since there is only going to be two commands being received that use modifiers, but I'm not sure how to implement that part either.
I would like my server to send the string received from my client (which I believe is msg
) and send it to the active window as a keypress. I would like to add an "IF" statement to the code so that if the server receives a certain message (the commands with modifiers; which are all known commands, so I could program which commands to listen for), it sends a specified keypress(depending on which command was received) to the active window.
UPDATE:
I've managed to figure out how to use SendKeys
to send the data from the client to the active window on the server machine. It was my original placement of the SendKeys
command that needed changing. I've updated it as follows:
//Write message in RichTextBox
string msg = encoder.GetString(message, 0, bytesRead);
WriteMessage(msg);
}
tcpClient.Close();
}
private void WriteMessage(string msg)
{
if (this.rtbServer.InvokeRequired)
{
WriteMessageDelegate d = new WriteMessageDelegate(WriteMessage);
this.rtbServer.Invoke(d, new object[] { msg });
}
else
{
this.rtbServer.AppendText(msg + Environment.NewLine);
// SEND KEYSTROKES TO ACTIVE WINDOW
SendKeys.Send(msg);
}
Now my problem is back to me being inexperienced with C#.
I'm not sure of the proper way to implement the IF
statement I need to catch the string before I send it to the active window. I need to use an IF
statement to catch the string first, because some of the messages coming from the server aren't formatted as proper keystrokes.
Basically, what I'd like to do is have anything that is just a single character slip by my IF
statement, and look for two particular messages.
The two messages I need to intercept are "CTRL-T" and "CTRL-H".
I don't know the proper formatting, since this is my first C# app, and I'm learning as I go, but my idea is to tell the program as follows:
If the message contained in the string is "CTRL-T" then SendKeys.Send("{^T}");
If the message contained in the string is "CTRL-H" then SendKeys.Send("{^H}");
If it is anything else then SendKeys.Send(msg);
Does that sound like the proper way to accomplish what I've explained here?
EDIT: I've attempted to figure out how to format my IF
statement, but it's obviously wrong:
// SEND KEYSTROKES TO ACTIVE WINDOW
if (msg.Equals("CTRL-T"))
{
SendKeys.Send("{^T}");
}
else if (msg.Equals("CTRL-H"))
{
SendKeys.Send("{^H}");
}
else
{
SendKeys.Send(msg);
}
I tested the first IF
statement by replacing "{^T}"
with "TEST"
and it sends the word TEST to notepad with no issues, but when I put in "{^T}"
, as soon as I hit the button to send that command, my server crashes.
The same thing happens for trying to send "{^H}"
Anyone have an idea what I'm doing wrong here?
I guess I'll answer my own question, since I've got the basic functionality that I was looking for now.
Basically, I wanted to accept a message from a client app, and display it in a text box on my server app, and then convert that message to simulated keypresses in the active window.
Before sending the keypresses to the window, I had to make sure that only the single digit keypresses were being sent to the active window immediately, and the other two known commands that needed modifiers attached to them were caught before being sent, and modified so they would act as modified keypresses, and not sent as a chunk of text (ie. "CTRL-T") instead of the actual "CTRL" button
+T button
//Write message in RichTextBox
string msg = encoder.GetString(message, 0, bytesRead);
WriteMessage(msg);
}
tcpClient.Close();
}
private void WriteMessage(string msg)
{
if (this.rtbServer.InvokeRequired)
{
WriteMessageDelegate d = new WriteMessageDelegate(WriteMessage);
this.rtbServer.Invoke(d, new object[] { msg });
}
else
{
this.rtbServer.AppendText(msg + Environment.NewLine);
// SEND KEYSTROKES TO ACTIVE WINDOW
if (msg.Equals("CTRL-T"))
{
SendKeys.Send("^T");
}
else if (msg.Equals("CTRL-H"))
{
SendKeys.Send("^H");
}
else
{
SendKeys.Send(msg);
}