I have a button code that enable the connection to the network whenever the user click it.
private void cmdConnect_Click(object sender, System.EventArgs e)
{
try
{
EnableCommands(true);
//Creating instance of Socket
m_socClient = new Socket (AddressFamily.InterNetwork,SocketType.Stream ,ProtocolType.Tcp );
// retrieve the remote machines IP address
IPAddress ip = IPAddress.Parse (txtIPAddr.Text);
//A printer has open port 9100 which can be used to connect to printer
int iPortNo = System.Convert.ToInt16 ( txtPort.Text);
//create the end point
IPEndPoint ipEnd = new IPEndPoint (ip.Address,iPortNo);
//connect to the remote host
m_socClient.Connect ( ipEnd );
EnableCommands(false);
//wait for data to arrive
WaitForData();
}
catch(SocketException se)
{
MessageBox.Show (se.Message );
EnableCommands(true);
}
page_counter();
}
However now I want this code to auto run first without anyone click on it. I want to do this because I want the task scheduler to run this code everyday to do update. This program will run behind, and theres no interaction with users. Therefore I want this program to auto connect by itself. Is this possible? Please advise.
You can put this code in a method instead of button click and call that method from button click event and also from the Form's constructor after InitializeComponent().
public partial class Sample : Form
{
public Sample()
{
InitializeComponent();
CmdConnect(txtIPAddr.Text, txtPort.Text);
}
private void cmdConnect_Click(object sender, System.EventArgs e)
{
CmdConnect(txtIPAddr.Text, txtPort.Text);
}
private void CmdConnect(string txtIPAddr, string txtPort)
{
try
{
EnableCommands(true);
//Creating instance of Socket
m_socClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
// retrieve the remote machines IP address
IPAddress ip = IPAddress.Parse(txtIPAddr);
//A printer has open port 9100 which can be used to connect to printer
int iPortNo = System.Convert.ToInt16(txtPort);
//create the end point
IPEndPoint ipEnd = new IPEndPoint(ip.Address, iPortNo);
//connect to the remote host
m_socClient.Connect(ipEnd);
EnableCommands(false);
//wait for data to arrive
WaitForData();
}
catch (SocketException se)
{
MessageBox.Show(se.Message);
EnableCommands(true);
}
page_counter();
}
// Other Methods
}
Call cmdConnect_Click(null, null) in your constructor or where ever you want it to run first.
You can raise click event of button control by calling PerformClick() on FormLoad() event. So it will auto run first without anyone clicking on it or when Task Scheduler runs your the application to do the update.
cmdConnect.PerformClick();
But I don't think sending click events is the best way.
If you just want to run the code which is in the try block from another place in the form, put the code into a separate method like DoWork() and call the method from anywhere you need to use it. That way you always have access to that function.
Example:
private void NetworkConnection()
{
try
{
EnableCommands(true);
//Creating instance of Socket
m_socClient = new Socket (AddressFamily.InterNetwork,SocketType.Stream ,ProtocolType.Tcp );
// retrieve the remote machines IP address
IPAddress ip = IPAddress.Parse (txtIPAddr.Text);
//A printer has open port 9100 which can be used to connect to printer
int iPortNo = System.Convert.ToInt16 ( txtPort.Text);
//create the end point
IPEndPoint ipEnd = new IPEndPoint (ip.Address,iPortNo);
//connect to the remote host
m_socClient.Connect ( ipEnd );
EnableCommands(false);
//wait for data to arrive
WaitForData();
}
catch(SocketException se)
{
MessageBox.Show (se.Message );
EnableCommands(true);
}
page_counter();
}
In Button Click event, just call NetworkConnection() method:
private void cmdConnect_Click(object sender, System.EventArgs e)
{
NetworkConnection();
}
Related
I have a project which needs to use WPF, C# to communicate and control a machine through COM port.
Program needs to control machine in below operation:
Program sends "command 1" to machine, then wait and validate reply from machine through COM port.
Once program verified correct reply from machine for command 1, program will send "command 2" to machine, then wait and validate reply again.
This operation repeats until all commands are executed.
I have done the COM port communication using SerialPort, DataReceived with SerialDataReceivedEventHandler. Testing using a button click event to send 1 command to machine, it works fine.
I would like to ask how to validate reply from machine for "command 1", after validation done, auto send next command to machine, validate reply and continue for a list of commands ?
Below is the code:
public partial class MainWindow : Window
{
SerialPort serial = new SerialPort();
string recieved_data; // get reply from machine through COM port
private void Connect_Comms(object sender, RoutedEventArgs e)
{
serial.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(Recieve);
}
private delegate void UpdateUiTextDelegate(string text);
private void Recieve(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
recieved_data = serial.ReadExisting();
Dispatcher.Invoke(DispatcherPriority.Send, new UpdateUiTextDelegate(updateUI), recieved_data);
}
private void updateUI(string text)
{ /* update GUI */ }
private void btnSend_Click(object sender, RoutedEventArgs e)
{
serial.Write("command 1");
// -> how to check reply 1 (recieved_data) before send command 2 ???
serial.Write("command 2");
// -> how to check reply 2 (recieved_data) before send command 3 ???
serial.Write("command 3");
}
}
I'm trying to open a TCP/IP listener but when I run the code below, it crashes. It doesn't give me an error because when it crashes, it freezes and stops responding.
TcpListener server = new TcpListener(IPAddress.Any, 619);
TcpClient client;
private void button3_Click(object sender, EventArgs e)
{
server.Start();
client = server.AcceptTcpClient();
if (client.Connected)
{
MessageBox.Show("connected");
}
}
I know for a fact this port is free so that's not it. it crashes on this line:
client = server.acceptTcpClient();
You're executing a blocking call on the UI thread which gives the appearance of a "Crashing" application.
You need to use another thread or do things asynchronously. Background worker might be a starting point.
private BackgroundWorker bgw = new BackgroundWorker();
public MainWindow()
{
InitializeComponent();
bgw.DoWork += Bgw_DoWork;
bgw.RunWorkerCompleted += Bgw_RunWorkerCompleted;
bgw.WorkerSupportsCancellation = true;
}
private void button3_Click(object sender, EventArgs e)
{
if (!bgw.IsBusy)
{
bgw.RunWorkerAsync();
((Button)sender).Content = "Cancel";
}
else
{
bgw.CancelAsync();
}
}
private void Bgw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
button.Content = "Start";
}
private void Bgw_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
var server = new TcpListener(IPAddress.Any, 619);
server.Start();
while (true)
{
if (worker.CancellationPending)
{
e.Cancel = true;
server.Stop();
break;
}
else
{
if (server.Pending())
{
var client = listener.AcceptTcpClient();
// handle client here or do something like below to return the client to the RunWorkerCompleted method in
// e.result
e.Result = client;
break;
}
}
}
}
There are other options such as using server.AcceptTcpClientAsync() instead of polling the server.Pending() property. Also, polling in this way without using Thread.Sleep in between may be overkill, i.e., you're checking the property very frequently and wasting cycles.
Following all of that, you need to figure out a way to deal with the client in a way that makes sense for your application. One click per client accepted? Handle new connections forever as they arrive until you cancel the listener? Etc. Good luck
BackgroundWorker tutorial
AcceptTcpClientAsync MSDN
This is expected behaviour. Your program hasn't crashed - the call to AccpetTcpClient() blocks waiting for an incoming connection:
https://msdn.microsoft.com/en-us/library/system.net.sockets.tcplistener.accepttcpclient(v=vs.110).aspx
You need to also open a TCP connection to port 619 from another thread, then your program will continue to run.
AcceptTcpClient is a blocking method
(https://msdn.microsoft.com/en-us/library/system.net.sockets.tcplistener.accepttcpclient%28v=vs.110%29.aspx).
When you call AcceptTcpClient, it will wait until a connection is made. Because it waits on the main thread (where also the GUI is running on), it will look like the program is frozen. Try using AcceptTcpClientAsync or putting the accepting part in a different thread. That should solve your problem.
Desirius
I'm creating a C# Socket Server, it already works, but now, when I press "Start" the "design" of the application doesn't load, it's not visible.
The socket server is running correcty (I see it working in the output window), I don't see any kind of error. I start deleting parts of the code, and the design stops being visible after this line:
TcpClient client = server.AcceptTcpClient();
...
If I remove from this line to the end, it appear again.
What's going on? (sorry for my bad english)
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
start();
}
private void start() {
TcpListener server = new TcpListener(IPAddress.Parse("127.0.0.1"), 1234);
server.Start();
TcpClient client = server.AcceptTcpClient();
Console.WriteLine("Client connected.");
}
I Think the problem is that the load is interrupted while the socket is working waiting for connections.
I'm trying to execute "start()" function on Form1_Shown but it does not work.
How can I be sure to start the socket server after the Form is full loaded?
server.AcceptTcpClient() is a blocking call and you are making it on the UI thread. You have a few options, here they are in the order I would do them.
Make the function you are calling it from async and use AcceptTcpClientAsync.
//Event handlers like `Load` are the only place you are allowed to do "async void"
private async void Form1_Load(object sender, EventArgs e)
{
await start();
}
private async Task start() {
TcpListener server = new TcpListener(IPAddress.Parse("127.0.0.1"), 1234);
server.Start();
TcpClient client = await server.AcceptTcpClientAsync();
Console.WriteLine("Client connected.");
}
If you can't use async/await because of the version of .NET you are targeting use BeginAcceptTcpClient to have a callback accept the client instead.
private void Form1_Load(object sender, EventArgs e)
{
start();
}
private void start() {
TcpListener server = new TcpListener(IPAddress.Parse("127.0.0.1"), 1234);
server.Start();
server.BeginAcceptTcpClient(AcceptClient, server);
}
private void AcceptClient(IAsyncResult result)
{
var server = (TcpListener)result.AsyncState;
TcpClient client = server.EndAcceptTcpClient(result);
Console.WriteLine("Client connected.");
}
Or one other option is put the code you currently have on a background thread via a Task.Run( or similar. However, I really would not recommend this approach, you tie up a thread just waiting for a new connection, the framework already provides better ways to do this without a thread by using async/await or the begin/end pair.
private void Form1_Load(object sender, EventArgs e)
{
Task.Run(() => start());
}
private void start() {
TcpListener server = new TcpListener(IPAddress.Parse("127.0.0.1"), 1234);
server.Start();
TcpClient client = server.AcceptTcpClient();
Console.WriteLine("Client connected.");
}
I have methos that recieve data from opening COM port:
private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
SerialPort sp = (SerialPort)sender;
try
{
if (sp.IsOpen)
{
if (sp.BytesToRead > 0)
{
// Get data
}
}
}
}
Also I have method that does connection to COM port:
private void connectPort()
{
SerialPort mySerialPort = new SerialPort(port);
...
}
When I call method that closes port:
mySerialPort.DiscardInBuffer();
mySerialPort.DiscardOutBuffer();
mySerialPort.Close();
After I get data from device still. What is wrong?
I don't know for sure, but from the docs it sounds like the fact that the data is being raised from another thread may be buffering and/or lagging a bit behind the actual data (plus it's possible for you to receive data between when you've discarded the buffer and when you close it).
I'd probably unhooking the DataReceivedHandler first, then close the connection, finally discard the data, ex.
mySerialPort.DataReceived -= new SerialDataReceivedEventHandler(DataReceivedHandler);
I have device that can connect to my laptop via blue-tooth as COM5. The device has a Pulse sensor. I want to draw data coming from sensor to graph. However when i connected to COM5 the serialport_Datarecieved event is not triggered. I tried device using matlab. It takes and draws data but i cant get data in c#. I checked the connection status of device and it is ok. I tried to change DtrEnabled and RtsEnapled properties but not worked.
private void Form1_Load(object sender, EventArgs e)
{
cmbPortList.Items.AddRange(SerialPort.GetPortNames());
cmbPortList.Sorted = true;
cmbPortList.SelectedIndex = 0;
this.serialPort1.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(serialPort1_DataReceived);
}
private void btnOpenPort_Click(object sender, EventArgs e)
{
try
{
serialPort1.PortName = cmbPortList.Text;
serialPort1.BaudRate = 9600;
serialPort1.DataBits = 8;
serialPort1.ReadTimeout = 500;
serialPort1.WriteTimeout = 500;
serialPort1.Handshake = Handshake.None;
if (!serialPort1.IsOpen)
{
btnRun.Enabled = true;
serialPort1.Open();
}
}
catch (Exception ex)
{
serialPort1.Close();
}
}
private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
while (serialPort1.BytesToRead > 0)
{
Thread.Sleep(50);
byte[] buffer = new byte[serialPort1.BytesToRead];
serialPort1.Read(buffer, 0, buffer.Length);
}
}
I cant read any data in buffer. There is led is flashing while device is not connected with via blue-tooth. So i am absolutely sure i connected to device.
Is problem about Bluetooth or code? Should i use another library to communicate blue tooth device?
I have read links below.
SerialPort fires DataReceived event after close
SerialPort not receiving any data
This may have less to do with the SerialPort and more to do with the way that Winforms threads are interacting with the serial port's background worker threads. See the solution to this for more info.
I think the designer of the circuit requests data from device with 's'. It must be about its protocol or hex code. I have found that code in matlab sample of circuit % Request Data fprintf(s,'s'); That's why i can read data when i use serialport.Write("Blast"); Also i tried all letters. Only 's' char triggers the event.