I'm using UdpClient to receive data from a single host(actually it's a microcontroller that sends 32 bytes of data every 4 milliseconds.
The program I wrote is pretty simple.
I'm initializing the UdpClient like this(in Program.cs):
public static UdpClient client = new UdpClient(1414);
after that i do this in Form_Load event:
static UdpClient client = Program.client;
IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0);
and then call the client.Recieve() like this:
Task.Run(() =>
{
while (true)
{
try
{
data = client.Receive(ref RemoteIpEndPoint);
}
catch (Exception ex)
{
String err_type = ex.GetType().Name;
if (err_type == "SocketException")
{
MessageBox.Show("Cannot Find The Device.", "Device Error.");
}
}
}
});
the program runs fine on my own system (using Windows 10). However when i run this program on windows 7,at random times,but with 100% chance client.Recieve() stops working and the program no longer receives any data. no exception is thrown. to find the root of the problem, I installed Wireshark to test if there is any incoming data.The answer was no(the LAN port light stops blinking too) . What has me confused is that this does not happen on windows 10.
The thing is, you miss all exceptions except SocketException.
To find out, what's going on, please, rewrite your catch block:
Task.Run(() =>
{
while (true)
{
try
{
data = client.Receive(ref RemoteIpEndPoint);
}
catch (SocketException ex)
{
MessageBox.Show("Cannot Find The Device.", "Device Error.");
}
catch (Exception e)
{
MessageBox.Show(e.GetType().Name, e.Message);
}
}
});
Turns out my code was completely fine.
This was a hardware problem on our side.
Related
I have a standalone test application developed in c# (4.5).
The application is primarily meant for sending some data to COM ports. The application accepts the data through the UI and the corresponding data is sent to respective COM ports.
For eg: Data from text box 1 goes to COM 1 on pressing a button, Data from Textbox 2 goes to COM 2 on pressing a different button etc.
Later I had to add a functionailty where a different set of data has to be accepted via Windows sockets and has to be sent to a different COM port other than above. This listening socket could receive data from multiple sources. If the listening socket receives back to back socket data, the application is expected to queue the data and process the data on a First come first serve bases.
Hence I created a synchronous socket to receive data. If the server receives data from 2 sources, it processes the data from source 1 and sends the completion status to source 1 and then takes the data from source 2,processes it and informs the status and this goes on. The socket is created on a thread so that it could receive and process data independently from the UI.
The application was meeting its objective as most of the communication was through sockets and people were not really using the UI for entering data.
Recently, as people started UI, i noticed a completely new issue. When someone tries to enters a data on to UI while the socket data is in process, it stops the socket data processing. When I press ctrl+Alt+Del on the host, it resumes the processing of the socket data.
I could not identify my mistake here. Also, I looked over to the Backgroundworkder class but I am not sure if that would allow the sockets commands to be processed in a synchronous way.
Please treat me as a newbie as I am still learning and complex suggestions might be hard to digest.
public partial class frm_bot : Form
{
public frm_bot()
{
StartServer();
}
private void frm_bot_Load(object sender, EventArgs e)
{
try
{
myThread = new System.Threading.Thread(new System.Threading.ThreadStart(OnClientConnect));
myThread.IsBackground = true;
myThread.Start();
}
catch (Exception ex)
{
showErrorMsg(ex.Message);
}//catch
}
public void StartServer()
{
InitializeComponent();
System.Net.IPAddress localIPAddress = System.Net.IPAddress.Parse(GetlocalIp());
IPEndPoint ipLocal = new IPEndPoint(localIPAddress, 8089);
_listener = new TcpListener(ipLocal);
}
private void OnClientConnect()
{
try
{
_listener.Start();
TcpClient clientSocket = default(TcpClient);
clientSocket = _listener.AcceptTcpClient();
_clientSocket = clientSocket;
ReadCallback();
}
catch (Exception se)
{
MessageBox.Show("Could not bind to Port 8089! Please close all Applications that uses Port 8089");
}
}
public void ReadCallback()
{
try
{
using (StreamReader sr = new StreamReader(_clientSocket.GetStream()))
using (StreamWriter sw = new StreamWriter(_clientSocket.GetStream()))
{
sw.AutoFlush = true;
char[] c = null;
while (sr.Peek() >= 0)
{
c = new char[25];
sr.Read(c, 0, c.Length);
Console.WriteLine(c);
}
string d = new string(c);
string[] cmddata = d.Split('\0');
string dataFromClient = cmddata[0];
if (dataFromClient.Length == 0)
{
Console.WriteLine("Client sent empty string!");
}
else
{
ProcessSocketData(dataFromClient);
sw.Write("Done");
}
sw.Close();
}
OnClientConnect();
}
catch (Exception ex)
{
OnClientConnect();
return;
}
}
public void ProcessSocketData(string sockdata)
{
try
{
// Socket data is processed here.
}
catch (Exception ex)
{
MessageBox.Show("Exception on ProcessSocketData: " + ex.Message);
return;
}
}
}
I have installed a Windows Service for my project, this error pop out when I start the service.
error 1503 the service didn't respond to the start or control request in a timely fashion
However, this project works fine when I debug in Visual Studio Code but when I use Visual Studio 2017 to create and start the service by following this tutorial and
Few solution I tried but the error still the same. Here are the solution I have tried.
Use CCCleaner to scan and fix issues
Modify ServicesPipeTimeout to 180000
The Logservice below can write the String into a text file, where I analyze the service run up until which part then fails. The service only able to run until LogService("3"); then it fails at receive the bytes from port.
Here is the code:
public Service1()
{
InitializeComponent();
LogService("server");
try
{
LogService("1");
IPEndPoint anyIP = new IPEndPoint(IPAddress.Any, 0);
UdpClient udpListener = new UdpClient(514);
byte[] bReceive; string sReceive; string sourceIP;
Console.WriteLine("Waiting...");
/* Main Loop */
/* Listen for incoming data on udp port 514 (default for SysLog events) */
while (true)
{
LogService("2");
try
{
LogService("3");
bReceive = udpListener.Receive(ref anyIP);
LogService("4");
/* Convert incoming data from bytes to ASCII */
sReceive = Encoding.ASCII.GetString(bReceive);
LogService(sReceive);
/* Get the IP of the device sending the syslog */
sourceIP = anyIP.Address.ToString();
LogService("5");
LogService(sourceIP);
new Thread(new logHandler(sourceIP, sReceive).handleLog).Start();
/* Start a new thread to handle received syslog event */
LogService(sReceive);
}
catch (Exception ex) { Console.WriteLine(ex.ToString()); }
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
throw ex;
}
}
I'm not sure if the error is occur because of the codes or other reasons
Update
Refer to this post, I tried to turn off the firewall to receive all the connection, but the error still remain the same.
There was once my project successfully listen the data from the server after I add udpListener.Client.Bind(anyIP); into the code, but then after some modification it is not functioning again. I'm not sure is the Bind() make the code works even just for once.
This is the way I solve my error refer to this post. Anyway, I'm not completely understand the process behind this, if anyone have some good example or link in explaining this solution please don't hesitate to comment below.
protected override void OnStart(string[] args)
{
LogService("Service started");
NewThread = new Thread(runSysLog);
NewThread.Start();
}
protected override void OnStop()
{
LogService("Service stopped");
StopRequest.Set();
//NewThread.Join();
}
public void runSysLog()
{
try
{
AutoResetEvent StopRequest = new AutoResetEvent(false);
/* Main Loop */
while (true)
{
if (StopRequest.WaitOne(5000)) return;
try
{
//while (udpListener.Available > 0)
if (udpListener.Available > 0)
{
//Some code here
}
}
catch (Exception ex)
{
LogService("Whileloop exception: " +ex.ToString());
throw ex;
}
}
}
catch (Exception ex)
{
LogService("Run Sys Log Exception: " +ex.ToString());
throw ex;
}
}
I have some problem with receiving frames in C#. After few hours from application start, some frames are lost.
Well, at start I'm running two threads which are receiving data. Code:
public void ATSListenerThreadA(MainWindow mainWindow)
{
UdpClient listenerA = new UdpClient(19001);
listenerA.Client.ReceiveBufferSize = 1000;
IPEndPoint remoteIPEndPointA = new IPEndPoint(IPAddress.Any, 1);
Byte[] receivedBytes;
try
{
while (mainWindow.ATSThreadActive)
{
receivedBytes = listenerA.Receive(ref remoteIPEndPointA);
if (receivedBytes.Length > 170)
{
Log.Write(MessageType.Info, "BUG KANAL A: " + BitConverter.ToString(receivedBytes));
}
mainWindow.ATSTimeoutTimer.Start();
ATSDataReceived(Channel.A, mainWindow, receivedBytes);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
public void ATSListenerThreadB(MainWindow mainWindow)
{
UdpClient listenerB = new UdpClient(19002);
listenerB.Client.ReceiveBufferSize = 1000;
IPEndPoint remoteIPEndPointB = new IPEndPoint(IPAddress.Any, 1);
Byte[] receivedBytes;
try
{
while (mainWindow.ATSThreadActive)
{
receivedBytes = listenerB.Receive(ref remoteIPEndPointB);
if (receivedBytes.Length > 170)
{
Log.Write(MessageType.Info, "BUG KANAL B: " + BitConverter.ToString(receivedBytes));
}
mainWindow.ATSTimeoutTimer.Start();
ATSDataReceived(Channel.B, mainWindow, receivedBytes);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void ATSDataReceived(Channel channel, MainWindow mainWindow, Byte[] received)
{
try
{
mainWindow.Dispatcher.Invoke(() =>
{
mainWindow.ATSStatusLabel.Foreground = System.Windows.Media.Brushes.Green;
mainWindow.ATSStatusLabel.Content = "OK";
});
ATSInterface.UpdateObjects(channel, received);
}
catch (Exception ex)
{
mainWindow.Dispatcher.Invoke(() =>
{
mainWindow.ATSStatusLabel.Foreground = System.Windows.Media.Brushes.Red;
mainWindow.ATSStatusLabel.Content = "ERR";
});
Log.Write(MessageType.Warning, ex.Message);
}
lock (this)
{
if (mainWindow.ATSTimeoutTimer != null)
{
mainWindow.ATSTimeoutTimer.Stop();
mainWindow.ATSTimeoutTimer.Start();
}
}
}
Then, in ATSDataReceived method, received data are processed with calling method ATSInterface.UpdateObjects(). Of course inside ATSInterface.UpdateObjects() method is lock. I was trying to receiving data synchronously and asynchronously, but it doesn't change anything. Also I was checking if two frames are not sticking together, but it's not this too. As I said, problem araises after few hours from program start, in both threads simultaneously.
I might add that frames are coming very often, once at ~150 ms.
What can be a reason?
some frames are lost.
That's perfectly normal for UDP. By design, you may or may not ever receive a datagram that was sent to you.
Other unreliable behaviors of UDP include the possibility that a given datagram may be received more than once, and that one datagram may be received after a different datagram that was sent later than it (i.e. the datagrams are not guaranteed to be received in the same order in which they were sent).
If you want reliable communications, you will need to use TCP, or add reliability features on top of your UDP protocol.
udp is unreliable protocol to use.
if you want to make sure that everything arrives you need to use TcpClient instead.
First question now answered if you want to skip to the bottom..
I'm developing comms between PDA's on .net 2.0 and our servers. Can't use WCF or I would have.
The comms model is like this:
And fortunately i've found working code form http://aviadezra.blogspot.com/2008/07/code-sample-net-sockets-multiple.html - that's where the image above comes from too.
The example app has messages from each client being broadcast to all other clients. I would like to be able to send a message from one client to another specific client. To do this i've modified the client app to have a from-ID and To-ID which is sent as part of the message.
Note: At this stage i'm doing proof of concept - i'll work on things like message headers (lengths, versions etc later).
From the project each client connection is handled by:
private void OnClientConnection(IAsyncResult asyn)
{
if (m_Closed)
{
return;
}
try
{
Socket clientSocket = m_socket.EndAccept(asyn);
RaiseClientConnected(clientSocket);
ConnectedClient connectedClient = new ConnectedClient(clientSocket);
connectedClient.MessageRecived += OnMessageRecived;
connectedClient.Disconnected += OnClientDisconnection;
connectedClient.StartListen();
long key = clientSocket.Handle.ToInt64();
if (m_clients.ContainsKey(key))
{
Debug.Fail(string.Format(
"Client with handle key '{0}' already exist!", key));
}
m_clients[key] = connectedClient;
// create the call back for any client connections...
m_socket.BeginAccept(new AsyncCallback(OnClientConnection), null);
}
catch (ObjectDisposedException odex)
{
Debug.Fail(odex.ToString(),
"OnClientConnection: Socket has been closed");
}
catch (Exception sex)
{
Debug.Fail(sex.ToString(),
"OnClientConnection: Socket failed");
}
}
Class connectedClient holds the socket for that client.
When I send a message from client I do a lookup to see if that's in my list of sockets:
if (ListIDSocket.ContainsKey(ToID))
{
PublishMessage(listLog, "ToID Found");
SendAll = false;
}
ListIDSocket is:
private Dictionary<string, Socket> ListIDSocket = new Dictionary<string, Socket>();
Then..
if (SendAll)
m_ServerTerminal.DistributeMessage(buffer);
else
m_ServerTerminal.SendToSocket(ToID, socket, buffer);
So if message is to anyone, call DistributeMessage; if to single user, call SendToSocket.
The code in m_ServerTerminal is:
public void DistributeMessage(byte[] buffer)
{
try
{
foreach (ConnectedClient connectedClient in m_clients.Values)
{
connectedClient.Send(buffer);
}
}
catch (SocketException se)
{
Debug.Fail(se.ToString(), string.Format(
"Buffer could not be sent"));
}
}
public void SendToSocket(string ToID, Socket DestSocket, byte[] buffer)
{
DistributeMessage(buffer); // This line works
ConnectedClient ToClient;
long keyval = DestSocket.Handle.ToInt64();
if (m_clients.ContainsKey(keyval))
{
ToClient = (ConnectedClient)m_clients[keyval];
try
{
ToClient.Send(buffer); // Nothing is received
}
catch (SocketException se)
{
Debug.Fail(se.ToString(), se.Message);
}
// DistributeMessage(buffer); // This code here doesn't work
}
}
DistributeMessage works fine. For debugging purposes i've included a call to DistributeMessage in my SendToSocket and this works if it's at the top.
If I move it down after I try writing to to the socket, it doesn't.
I don't get an exception on either way.
As it stands now, client gets one message when it should get two - one from DistributeMessage and one from SendToSocket.
The code for connectedclient.Send is:
public void Send(byte[] buffer)
{
if (m_clientSocket == null)
{
throw new Exception("Can't send data. ConnectedClient is Closed!");
}
m_clientSocket.Send(buffer);
}
Questions:
I can't see anything that i'm doing substantially different with my new code to existing but the socket isn't being written to. Can anyone spot anything obvious ? Is this something to do with sockets, handles and references to them ?
EDIT: Bug found, whilst I was looking up to see if the socket existed, I was passing in the socket of the sender not receiver. I'll fix this.
Debugging DLL's I'd still like to know about though..
Secondly, the project is setup with the socket handling in it's own DLL called Communication.Sockets.Core. I've never built DLL's before and i'm having trouble debugging. Can't use normal debug points in code - I resorted to creating a form to display instead.
Any tips on how to debug DLL's ?
I'm still fairly new to C#; just on 1 year.
TIA,
Andrew
I make an application in android can send character code to server C# when user input on android keyboard.
This is send method in android side:
public Boolean writeMessage(String message) {
try {
printWriter = new PrintWriter(socket.getOutputStream(), true);
printWriter.println(message);
return true;
} catch (Exception ex) {
Log.e(TAG,"write error: " +ex.getMessage());
return false;
}
}
And server listen the messages (C#):
Thread myThread = new Thread(new ThreadStart(ServeClient));
myThread.Start();
void ServeClient(){
StreamReader reader = new StreamReader(tcpClient.GetStream());
while (true)
{
try
{
String message = reader.ReadLine();
if (message != null)
{
Console.WriteLine(message);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
My code works, but when user input faster, the server delay read message in 1,2 or 3 seconds (I have test the method get character when user input, it works fine, not delay). Where is my problem? Thanks in advance!
Your problem may be caused by Nagle's algorithm reducing TCP traffic. Consider setting TCP_NODELAY on your client (and server - TcpClient.Client.NoDelay - if communication is two-way).
Edit: For java it is Socket.setTcpNoDelay method.