Manipulate remote machine control events


In this article I will explain, how in a Peer to Peer Windows application, one can change or access remote machine control events, such as radio button or combobox, from current user machine. I have discussed a basic example here.

In this article I will explain, how in a Peer to Peer Windows application, one can change or access remote machine control events, such as radio button or combobox, from current user

I would like to show here how on a Peer to Peer network windows application, you can manipulate the control events of remote machine from current machine.

The Scenario:
For eg.
I want a Peer to Peer application to be run on System1 and System2

My default form look of the application is like this:
default look

On selecting the remote system the application (running on both System1 and System2) will be listening(connected) to each other.

And if I select ASP Image Radio Button on System1 , Lock Image Radio Button will automatically selected in System2 and vice versa.
And if I select Lock Image Radio Button on System1 , Asp Image Radio Button will automatically selected in System2 and vice versa

For eg.
On System1 I Clicked Lock Radio Button.
lockimage

And on System2 the aspImage Radio Button will be selected automatically.
aspimage

It should not be system dependent, which means on which ever system I select a radio button the other radio button will be selected automatically on other machine.

That means that we are controlling the control events of System1 or System2
from System2 or System1 respectively.

So lets get started:
First to select the remote computer I have used a class "NetworkBrowser"
I have attached the class with the application below.(I won't be discussing about the class, because its not our problem domain here)
For more information on "NetworkBrowser" look here:
http://www.codeproject.com/KB/IP/ListNetworkComputers.aspx

Necessary "using"



using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.IO;


Declaring necessary variables



#region variables

private string hostName; //For Host Machine Name

private Socket serverSocket; //The server has a socket to listen on

//Only one of the server or client will establish a connection
private Socket activeConnection;
private byte[] receiveBuffer;
private byte[] sendBuffer;

//Since only one of the connections get used, the label for the remote system must change
private string remoteLabel;

//Consolidate the received data until there is enough
private byte[] bufferToRead;
private int bytesReceived;

//for thread operations.
public Thread thread = null;

//Track the settings
private bool aspImageStatus;
private bool lockImageStatus;

#endregion


The Form's constructor



public p2pForm()
{
InitializeComponent();

hostName = Dns.GetHostName();

//Set up the buffer for receiving the message and salt value from the remote system
bufferToRead = new byte[16];
bytesReceived = 0;

//Initialise the process status flags

aspImageStatus = false;
lockImageStatus = false;

}


Form_Load event



private void Form1_Load(object sender, EventArgs e)
{
//create a new NetworkBrowser object, and get the
//list of network computers it found, and add each
//entry to the combo box
try
{
aspImageStatus = false;
lockImageStatus = false;

pictureBox1.Visible = false;
pictureBox2.Visible = false;

//Get list of available networks
NetworkBrowser browser = new NetworkBrowser();
foreach (string pc in browser.getNetworkComputers())
{
OtherComputersCombo.Items.Add(pc);
}
statusLabel.Text = "List of remote systems loaded.";
}
catch ( Exception ex )
{
statusLabel.Text = "Error retrieving list of remote systems.";
MessageBox.Show(": REASON :\n " + ex);
}
finally
{
//Start the server on the local machine and display the name
startServer();
}

}


"startServer" method



private void startServer()
{
try
{

//Set up a socket attached to the relevant port listening on all addresses
IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, 5050);
serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);


serverSocket.Bind(localEndPoint);
serverSocket.Listen(1);

//Bind the event handler for dealing with connections
serverSocket.BeginAccept(new AsyncCallback(onClientConnect), null);

//Update the status message
statusLabel.Text = "Server Started on " + hostName + ".";

}
catch
{
statusLabel.Text = " Cannot be connected ";
DialogResult dr = MessageBox.Show("Do you want to continue \n"+
"Yes : Continue as server \n No : Exit the application",
"Server Disconnected", MessageBoxButtons.YesNo);
switch (dr)
{
case DialogResult.Yes:
Application.Restart();// restarts the application
break;
case DialogResult.No:
Application.Exit();// Application closes
break;
default:
Application.Exit();
break;
}
}

}


Selecting the remotemachine using "ComboBox"



private void OtherComputersCombo_SelectedIndexChanged(object sender, EventArgs e)
{
try
{
//Set up the client socket
activeConnection = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

//Create the end point based on the newly selected remote system, taking
//the first IP address returned for it
IPAddress remoteAddress = Dns.GetHostAddresses(OtherComputersCombo.Text)[0];
IPEndPoint remoteEndPoint = new IPEndPoint(remoteAddress, 5050);

// and connect the socket to the endpoint
activeConnection.Connect(remoteEndPoint);

//TODO: set the status string to indicate the connection to server

//Set the label for the remote system
remoteLabel = "server";

//Bind the event handler for dealing with incoming data
receiveBuffer = new byte[1];

activeConnection.BeginReceive(
receiveBuffer, 0,
receiveBuffer.Length,
SocketFlags.None,
new AsyncCallback(onDataReceived),
activeConnection
);

statusLabel.Text = " Connected to: " + OtherComputersCombo.Text + " as Server ";

settingPanel.Visible = true;
//machineSettingRadioButton.Visible = true;
//applicationSettingRadioButton.Visible = true;
OtherComputersCombo.Enabled = false;

}
catch
{
statusLabel.Text = " " + OtherComputersCombo.Text + " Not Found : ";
}
}


When the client send for a request for connection



private void onClientConnect(IAsyncResult asyn)
{
try
{
//Get the connection object
activeConnection = serverSocket.EndAccept(asyn);

//on Client connect
statusLabel.Text = "Client Connected";

//Set the label for the remote system
remoteLabel = "client";

//Bind the event handler for dealing with incoming data
receiveBuffer = new byte[1];

activeConnection.BeginReceive(
receiveBuffer, 0,
receiveBuffer.Length,
SocketFlags.None,
new AsyncCallback(onDataReceived),
activeConnection
);

//Creates a new thread for Events Enabling on client connect
thread = new Thread(delegate()
{
this.BeginInvoke((ThreadStart)delegate()
{
this.settingPanel.Visible = true;
this.OtherComputersCombo.Enabled = false;

});

});
thread.Start();

//If we were going to accept more connections we'd call BeginAccept here, but we only want one
}//end of try{}
catch
{
statusLabel.Text = "Client Not-connected";
}//end of catch
}


The "Important" part, working on Radio Buttons


On click on the respective Radio buttons the event sends a message to the remote machine.
This message is captured by the onDataReceived() Method on the remote machine, which we will discuss next.

//on aspImage RadioButton click
private void aspImageRadioButton_CheckedChanged(object sender, EventArgs e)
{
pictureBox2.Visible = false;
pictureBox1.Visible = true;
if (lockImageStatus == false)
{
string setting = "asp image ";
sendBuffer = Encoding.ASCII.GetBytes(setting);

activeConnection.Send(sendBuffer);
}
lockImageStatus = false;
lockImageStatus = false;
}

//on lockImage RadioButton click
private void lockImageRadioButton_CheckedChanged(object sender, EventArgs e)
{
pictureBox2.Visible = true;
pictureBox1.Visible = false;
if (aspImageStatus == false)
{
string setting = "lock image ";
sendBuffer = Encoding.ASCII.GetBytes(setting);

activeConnection.Send(sendBuffer);
}
aspImageStatus = false;
lockImageStatus = false;
}


"The Main Part", onDataReceived() Method


In this method the remote machine recieves the data and works on the scenario mentioned earlier.

public void onDataReceived(IAsyncResult asyn)
{
int receiveLength = 0;

try
{
statusLabel.Text = "Receiving from " + remoteLabel + ".";

//To store the message recieved from remote machine
string textFormRemote = "";

// Complete the BeginReceive() asynchronous call by EndReceive() method
// which will return the number of bytes written to the stream
// by the client
receiveLength = activeConnection.EndReceive(asyn);

//Copy the received bytes from the socket buffer to the bufferToRead
Buffer.BlockCopy(receiveBuffer, 0, bufferToRead, bytesReceived, receiveLength);
bytesReceived += receiveLength;

//Get the complete message from the remote system
activeConnection.BeginReceive(
receiveBuffer, 0,
receiveBuffer.Length,
SocketFlags.None,
new AsyncCallback(onDataReceived),
activeConnection
);

//The message recieved from remote system should be of 16 bytes
if (bytesReceived == 16)
{
//convert the bytes recieved into string
textFormRemote = Encoding.ASCII.GetString(bufferToRead);

//If Asp Image radio button clicked on remote system
if (textFormRemote == "asp image ")
{
thread = new Thread(delegate()
{
this.BeginInvoke((ThreadStart)delegate()
{
this.statusLabel.Text = "P2P Form Lock Image Mode";
aspImageStatus = true;
lockImageStatus = true;
this.lockImageRadioButton.Checked = true;
bytesReceived = 0;
receiveLength = 0;

});

});
thread.Start();

}
//If Lock Image radio button clicked on remote system
else if (textFormRemote == "lock image ")
{

thread = new Thread(delegate()
{
this.BeginInvoke((ThreadStart)delegate()
{
this.statusLabel.Text = "P2P Form Set to Asp Image";
lockImageStatus = true;
aspImageStatus = true;
this.aspImageRadioButton.Checked = true;
bytesReceived = 0;
receiveLength = 0;
});

});
thread.Start();

}

//Reset the ofsets
bytesReceived = 0;
receiveLength = 0;

}//end of if statement bytesReceived == 16
}//end of try{}
catch(Exception ee)
{
statusLabel.Text = "Transmission Disconnected ";

//Opens a Message box on being disconnected
//Asks for if user want to close the application or continue as a server
DialogResult dr = MessageBox.Show("Do you want to continue as Server \n "+
"Yes : Continue as server \n No : Exit the application",
"Server Disconnected",MessageBoxButtons.YesNo);
switch (dr)
{
case DialogResult.Yes:

activeConnection.Shutdown(SocketShutdown.Both);
activeConnection.Close();
activeConnection = null;
Application.Restart();
//startServer();
//PasswordBox.Enabled = false;
//GenKeyButton.Enabled = false;
break;
case DialogResult.No:
Application.Exit();
break;
default:
Application.Exit();
break;
}//end of switch()
}//end of catch{}
}


Now here is our solution completed.

" THE END "



I am also attaching the Application I discussed here.

if you have any doubts, give a response.

Cheers
Paul


Attachments

  • sampleapp (40824-570-P2PForm.rar)
  • Comments

    No responses found. Be the first to comment...


  • Do not include your name, "with regards" etc in the comment. Write detailed comment, relevant to the topic.
  • No HTML formatting and links to other web sites are allowed.
  • This is a strictly moderated site. Absolutely no spam allowed.
  • Name:
    Email: