Design don't appear on Debug - c#

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.");
}

Related

C# Supersimpletcp Allow any client to have only one connection

i am using Supersimpletcp C# library and TCP server code is here:
using SuperSimpleTcp;
void Main(string[] args)
{
// instantiate
SimpleTcpServer server = new SimpleTcpServer("127.0.0.1:9000");
// set events
server.Events.ClientConnected += ClientConnected;
server.Events.ClientDisconnected += ClientDisconnected;
server.Events.DataReceived += DataReceived;
// let's go!
server.Start();
// once a client has connected...
server.Send("[ClientIp:Port]", "Hello, world!");
Console.ReadKey();
}
static void ClientConnected(object sender, ConnectionEventArgs e)
{
Console.WriteLine($"[{e.IpPort}] client connected");
}
static void ClientDisconnected(object sender, ConnectionEventArgs e)
{
Console.WriteLine($"[{e.IpPort}] client disconnected: {e.Reason}");
}
static void DataReceived(object sender, DataReceivedEventArgs e)
{
Console.WriteLine($"[{e.IpPort}]: {Encoding.UTF8.GetString(e.Data.Array, 0, e.Data.Count)}");
}
On TCP Server implementation, I want to allow any client to have just one connection, if a previously connected client reconnects, previous connection must die, how can I provide it?
I researched on google and could not find any solution, documentation or tutorial for supersimpletcp.
If you guys have any suggestion, any kind of simple TCP library that provides good configuration oppurtunities etc., feel free to tell me.

Cannot start a simple TCP/IP client

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

Auto click button in winform c#

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();
}

Trying to make a basic TCP client in WPF

I am trying to implement a basic TCP client in WPF. I have managed to to this using windows forms but can't get it working in WPF. I have tried going back to the very basics and adding things bit by bit. This is to connect to an arduino that is outputing single lines of code. I can successfully connect to it through telnet so the problem is with my code.
This is what I have so far:
public partial class MainWindow : Window
{
private TcpClient tcp;
private StreamWriter SwSender;
private StreamReader SrReciever;
private Thread thrMessaging;
private delegate void UpdateLogCallBack(string strMessage);
public MainWindow()
{
InitializeComponent();
}
private void btn_Connect_Click(object sender, RoutedEventArgs e)
{
TcpClient tcp = new TcpClient();
txt_Log.AppendText("connecting");
tcp.Connect(IPAddress.Parse("192.168.137.1"), 2000);
txt_Log.AppendText("Connected");
thrMessaging = new Thread(new ThreadStart(ReceiveMessages));
thrMessaging.Start();
}
private void ReceiveMessages()
{
SrReciever = new StreamReader(tcp.GetStream());
while (true)
{
string response = SrReciever.ReadLine();
txt_Log.Dispatcher.Invoke(new UpdateLogCallBack(this.UpdateLog), new object[] { response });
}
}
private void UpdateLog(string strMessage)
{
txt_Log.AppendText(strMessage);
}
}
}
Running this gives me an error in the Receive messages method. It says the error is on the line with "SrReciever = new StreamReader(tcp.GetStream());" saying it a NullReferenceException, Object reference not set to an instance of an object.
I'm not the best at programming, so if there is an example out there for a TCP client that works in WPF then that will be very helpful.
Thanks
Nick
That is simply because you're creating a scoped variable here:
private void btn_Connect_Click(object sender, RoutedEventArgs e)
{
//TcpClient tcp = new TcpClient();
//this initialized a new tcp variable only here...
//do this instead...
tcp = new TcpClient();
//this will assign a new TcpClient to MainWindow.tcp
So what happens is MainWindow.tcp is actually null and then when ReceiveMessages is called you are trying to call GetStream a null value.

c# Thread won't add Row to DataGridView CrossThreadError

I am learning c# and I would like to know why my code won't add a row to my DataGridView in the ReceivePacket area. It works in the SendPacket but not in the other.
The purpose is to simply send a UDP packet to a machine, thanks in advance.
Here is my code:
private void btnSend_Click(object sender, EventArgs e)
{
SendPacket();
}
private void btnReceiving_Click(object sender, EventArgs e)
{
Thread thread = new Thread(new ThreadStart(reciev));
thread.Start();
}
UdpClient client = new UdpClient();
public void SendPacket()
{
byte[] packet = Encoding.ASCII.GetBytes(DateTime.Now.ToString("HH:mm:ss:ff"));
client.Send(packet, packet.Length, tbIP.Text, 444);
dgvSend.Rows.Add(DateTime.Now.ToString("HH:mm:ss:ff"));
}
public void ReceivePacket(byte[] packet)
{// it goes wrong here, because it gives a crossthread error
dgvReceiv.Rows.Add(Encoding.ASCII.GetString(packet), DateTime.Now.ToString("HH:mm:ss:ff"));
}
public void reciev()
{
UdpClient client = new UdpClient(444);
while (true)
{
IPEndPoint server = new IPEndPoint(IPAddress.Any, 0);
byte[] packet = client.Receive(ref server);
ReceivePacket(packet);
}
}
I fixed it using this line of code instead of the normal (with the invoke :) ):
dgvReceiv.Invoke(new MethodInvoker(delegate { dgvReceiv.Rows.Add(Encoding.ASCII.GetString(packet), DateTime.Now.ToString("HH:mm:ss:ff")); }));
Here you go example of using delegates to invoke actions from other threads on controls created on main thread.
http://msdn.microsoft.com/en-us/library/zyzhdc6b.aspx
The problem is that you're attempting to create a GUI element (a form) on another thread than the main GUI thread. You can only create GUI elements on the GUI thread. Anything else doesn't work.
You should receive the data in your secondary thread, and then copy it over to your GUI thread, to put it inside a GUI element. I think there's a function Control.Invoke that is a delegate that will invoke a function on the thread the Control was created on, which you could use to call from your secondary thread to actually populate your form or whatever control.

Categories