Using C# UDP Client - c#

I'm making a program which needs to be listening for UDP Data at all times.
My current idea is have this method running constantly in one thread listening for packets and then adding them to a list ready to be dealt with in other threads. The main problem is I would also like to add the received IP to a list so that the other thread can deal with it but I don't know if the program stops using the Receive method for a moment if it will lose packets received while processing the data or if it can still grab them from a queue.
public void listen()
{
try
{
packetQueue.Add(receivingUdpClient.Receive(ref RemoteIpEndPoint));
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}

network traffic should be buffered on your network card so the data should be consistent even if you are listening inconsistently. as for the IP you can get it from the endpoint so you'll need to pass that as well:
public void listen()
{
try
{
packetQueue.Add(receivingUdpClient.Receive(ref RemoteIpEndPoint), RemoteIpEndPoint);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
If you want to miss as little time as possible in between receives I suggest you use BeginReceive and start a new BeginReceive in the callback before processing the received data in the callback. this will add some synchronization complexity though.

I know of no way to get the IP from the Udp packet. You need to get it form the EndPoint:
byte[] receivedBytes = oClientListener.Receive(ref endPoint);
IPAddress = endPoint.Address;
PackQueue.Add( new PacketOfSomeType( receivedBytes, IPAdress ) );
Also, your program will need to run VERY SLOWLY to start losing any packets - windows will buffer those for you, so long as you have your client listener set up!

Related

UdpClient beginreceive how to detect when server is off

I have an application that is reading data from a Udp server on 32 different ports that I need to process. I'm using the UdpClient.BeginReceive that is calling itself because I want to listen all the time :
private void ProcessEndpointData(IAsyncResult result)
{
UdpClient client = result.AsyncState as UdpClient;
// points towards whoever had sent the message:
IPEndPoint source = new IPEndPoint(0, 0);
// schedule the next receive operation once reading is done:
client.BeginReceive(new AsyncCallback(this.ProcessEndpointData), client);
// get the actual message and fill out the source:
this.DecodeDatagram(new DatagrammeAscb()
{
Datagramme = this.ByteArrayToStructure<Datagram>(client.EndReceive(result, ref source))
});
}
When I stop the server side, the function is waiting for data (that is normal behavior). What I would like to do is to detect when the server is disconnected and then close all my clients.
I'm asking myself if I should use sockets class to have more controls or just maybe I'm missing something here.
Anyway thanks for your help.

SocketException with Unity C# UDP Receive

I'm using Unity and I'm trying to listen to UDP packets coming in on a specific port. In Unity I have an object with a script attached and the script is designed to simply listen and record data coming in off of the UDP packets. In the script I have my Start function:
public void Start() {
// Setup listener.
this.mListener = new IPEndPoint(IPAddress.Loopback, 0);
// Setup background UDP listener thread.
this.mReceiveThread = new Thread(new ThreadStart(ReceiveData));
this.mReceiveThread.IsBackground = true;
this.mReceiveThread.Start();
}
The function setups the IPEndPoint and the receive thread, then starts the receive thread which is defined as:
private void ReceiveData() {
try {
// Setup UDP client.
this.mClient = new UdpClient(30020);
this.mClient.Client.ReceiveTimeout = 250;
// While thread is still alive.
while(Thread.CurrentThread.IsAlive) {
try {
// Grab the data.
byte[] data = this.mClient.Receive(ref this.mListener);
// Convert the data.
/* REDACTED */
// Separate out the data.
/* REDACTED */
// Store data in the DataSource.
/* REDACTED */
} catch(SocketException e) {
Debug.Log(e.ToString());
continue;
}
}
} catch(Exception e) {
Debug.Log(e.ToString());
}
}
However, when I try to run this I keep getting the following SocketException:
System.Net.Sockets.SocketException: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.
This code was working for months, and I've never seen this exception before. It doesn't really make sense to me. I've tried changing the port but it doesn't seem to have any effect. I'm not exactly sure what happened, or what changes I made that made it behave this way. I have not updated Unity since I started this project. Could my other program not be sending any UDP packets out? Could a lack of UDP packets be the cause of this? The frequency that this SocketException appears in my log is related to the ReceiveTimeout property...

Want a .Net Socket Event Handler for incoming data

I'm rewriting an ancient VB6 program in C# (.Net Framework 4.0). It communicates with a piece of industrial equipment on the factory floor. VB6 used some old COM-based socket software; I'm using the .Net Socket class.
When I send a message to the equipment I expect a response back so I know to listen for one then. But the equipment can also send messages asynchronously without warning (say, to indicate a failure or problem). So I always have to receive those. So what I'd really like is an event handler that gets called whenever anything comes in from the equipment.
The Socket class seems to use a BeginReceive/EndReceive scheme for receive event handling. Can I just do a BeginReceive once at the start of my program to define an event-handler for all incoming messages, or do I have to constantly be doing BeginReceive/EndReceive's throughout my program?
Thanks in advance for clarifying the correct way to do this.
Are you the server?
If you are the server, you will listen for a socket connection, and then accept the socket connection and store it. You will then call BeginReceive with the stored socket. In the BeginReceive method, you will provide a callback function to receive, and handle the data.
Once you receive data, the callback happens. The callback function will call EndReceive on the stored connection. This is where you get/handle the data. You will also call BeginReceive again to wait for more data.
This way, the BeginReceive and EndReceive will run in a circle: you are always receiving data, and waiting for more data.
Here is an example:
void WaitForData(SocketState state)
{
try
{
state.Socket.BeginReceive(state.DataBuffer, 0, state.DataBuffer.Length, SocketFlags.None, new AsyncCallback(ReadDataCallback), state);
}
catch (SocketException se)
{
//Socket has been closed
//Close/dispose of socket
}
}
public void ReadDataCallback(IAsyncResult ar)
{
SocketState state = (SocketState)ar.AsyncState;
try
{
// Read data from the client socket.
int iRx = state.Socket.EndReceive(ar);
//Handle Data....
WaitForData(state);
}
catch (ObjectDisposedException)
{
//Socket has been closed
//Close/dispose of socket
}
catch (SocketException)
{
//Socket exception
//Close/dispose of socket
}
}
EDIT:
As per your comment, here is an example of a C# asynchronous client: http://msdn.microsoft.com/en-us/library/bbx2eya8.aspx.
The BeginReceive/EndReceive work similar to the server.

Sending and receiving UDP packets in .NET

I am trying to test UDP communications on a LAN. I have a small piece of code to and I have tried to run it in 2 computers (one should wait to receive and the other one should send). The strange thing is that computer A sends and B receives properly but if I try A to receive and B to send it does not work. Do you know why could it be?
public void SendBroadcast(int port, string message)
{
UdpClient client = new UdpClient();
byte[] packet = Encoding.ASCII.GetBytes(message);
try
{
client.Send(packet, packet.Length, IPAddress.Broadcast.ToString(), port);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
public void Receive(int port)
{
UdpClient client = null;
try
{
client = new UdpClient(port);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
IPEndPoint server = new IPEndPoint(IPAddress.Any, 0);
while (true)
{
try
{
byte[] packet = client.Receive(ref server);
Console.WriteLine("{0}, {1}", server, Encoding.ASCII.GetString(packet));
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
And the calls:
SendBroadcast(444, "hello"); Receive(444);
If I run 2 instances of the program on the same computer it works properly but creates 3 packages per call.
Thanks in advance.
Try using the async methods so that you can keep listening for messages without blocking to send messages.
Well, if the same code works on one and not the other, it's your environment. Check your firewall settings, make sure it's not preventing the broadcast on the sender or preventing receipt on the receiver. Wireshark (or even Windows' netmon) should be helpful here.
What networking gear is inbetween these two systems?
Are the two systems on the same subnet with the same subnetmask?
There's a funny thing with IPV4 networks; you can have multiple broadcast addresses. You can broadcast to the local network or to the local subnet. These are distinctly different addresses, and if one system's IP setup is different it may not realize that it should listen for this local subnet broadcast.
Things to try:
Ensure IPV6 is disabled on both ends (IPV6 doesn't support broadcast address, but lets just establish a baseline).
Explictly set the IP address in the program, does it work? My guess will be yes, so we have to determine why.
Load up wireshark and sniff the packets. See if they are making it all the way to the remote host, and he is just ignoring them.
When trying to do this asynchronously, Microsoft neglects to tell users to create their own partial class like this (see below). Very simple, but without this, it can be difficult to read through their examples.
private partial class UdpState
{
public UdpClient u;
public IPEndPoint e;
}

How can I unbind a socket in C#?

I'm having some problems reusing a server socket in a test application I've made. Basically, I have a program that implements both the client side and the server side. I run two instances of this program for testing purposes, one instance starts to host and the other connects. This is the listening code:
private void Listen_Click(object sender, EventArgs e)
{
try
{
server = new ConnectionWrapper();
HideControls();
alreadyReset = false;
int port = int.Parse(PortHostEdit.Text);
IPEndPoint iep = new IPEndPoint(IPAddress.Any, port);
server.connection.Bind(iep); // bellow explanations refer to this line in particular
server.connection.Listen(1);
server.connection.BeginAccept(new AsyncCallback(OnClientConnected), null);
GameStatus.Text = "Waiting for connections on port " + port.ToString();
}
catch (Exception ex)
{
DispatchError(ex);
}
}
private void OnClientConnected(IAsyncResult iar)
{
try
{
me = Player.XPlayer;
myTurn = true;
server.connection = server.connection.EndAccept(iar); // I will only have one client, so I don't care for the original listening socket.
GameStatus.Text = server.connection.RemoteEndPoint.ToString() + " connected";
StartServerReceive();
}
catch (Exception ex)
{
DispatchError(ex);
}
}
This works fine the first time. However, after a while (when my little game ends), I call Dispose() on the server object, implemented like this:
public void Dispose()
{
connection.Close(); // connection is the actual socket
commandBuff.Clear(); // this is just a StringBuilder
}
I also have this in the object constructor:
public ConnectionWrapper()
{
commandBuff = new StringBuilder();
connection = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
connection.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
}
I get no error when I click the Listen button a second time. The client side connects just fine, however my server side does not detect the client connection a second time, which basically renders the server useless anyway. I'm guessing it's connecting to the old, lingering socket, but I have no idea why this is happening to be honest. Here's the client connection code:
private void Connect_Click(object sender, EventArgs e)
{
try
{
client = new ConnectionWrapper();
HideControls();
alreadyReset = false;
IPAddress ip = IPAddress.Parse(IPEdit.Text);
int port = int.Parse(PortConnEdit.Text);
IPEndPoint ipe = new IPEndPoint(ip, port);
client.connection.BeginConnect(ipe, new AsyncCallback(OnConnectedToServer), null);
}
catch (Exception ex)
{
DispatchError(ex);
}
}
If I do netstat -a in CMD, I see that the port I use is still bound and its state is LISTENING, even after calling Dispose(). I read that this is normal, and that there's a timeout for that port to be "unbound".
Is there a way I can force that port to unbind or set a very short timeout until it automatically gets unbound? Right now, it only gets unbound when I exit the program. Maybe I'm doing something wrong in my server? If so, what could that be? Why does the client connect fine, yet the server side doesn't detect it a second time?
I could make the socket always listen, not dispose it, and use a separate socket to handle the server connection, which would probably fix it, but I want other programs to be able to use the port between successive play sessions.
I remember seeing another question asking this, but there was no satisfactory answer for my case there.
There may be a couple of reasons why the port would stay open, but I think you should be able to resolve your issue by using an explicit LingerOption on the socket:
LingerOption lo = new LingerOption(false, 0);
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger, lo);
This basically turns the socket shutdown into an abortive shutdown instead of a graceful shutdown. If you want it to be graceful but just not wait as long, then use true in the constructor and specify a small but nonzero value for the timeout.
I just noticed this line, which is almost undoubtedly part of your problem:
server.connection = server.connection.EndAccept(iar); // I will only have one client, so I don't care for the original listening socket.
The comment you've written here is, well, wrong. Your wrapper class really shouldn't allow connection to be written to at all. But you cannot simply replace the listening socket with the client socket - they're two different sockets!
What's going to happen here is that (a) the listening socket goes out of scope and therefore never gets explicitly closed/disposed - this will happen at a random time, possibly at a nasty time. And (b) the socket that you do close is just the client socket, it will not close the listening socket, and so it's no wonder that you're having trouble rebinding another listening socket.
What you're actually witnessing isn't a socket timeout, it's the time it takes for the garbage collector to realize that the listening socket is dead and free/finalize it. To fix this, you need to stop overwriting the listening socket; the Dispose method of your wrapper class should dispose the original listening socket, and the client socket should be tracked separately and disposed whenever you are actually done with it.
In fact, you should really never need to rebind another listening socket at all. The listening socket stays alive the whole time. The actual connection is represented by just the client socket. You should only need to dispose the listening socket when you finally shut down the server.
I agree with the previous answer, you should also "shutdown" to allow any existing activity to complete and then close the socket flagging it for reuse...
socket.Shutdown(SocketShutdown.Both);
socket.Disconnect(true);

Categories