I'm using UDP sockets to communicate a C++ application with a C# application.
In the C# -> C++ direction everything seems to be working fine, but the other way around is the one that's driving me nuts.
Communication does work, but messages are getting way late (like 2 secs delay) in the C# app, even though they're being sent every frame (it's a 3D app), and the receiving code is executing every 10 ms.
I need real time so this is a very painful problem. Do you think this might be related to packet losses? Then why don't they get lost in the other direction?
EDIT:
C# app code for syncing data:
public void RecibeDatos() { if (MessageReceived && U != null && S != null) { MessageReceived = false; //Console.WriteLine("listening for messages"); U.BeginReceive(ReceiveCallback, S); } } public void ReceiveCallback(IAsyncResult ar) { UdpClient u = ((UdpState)(ar.AsyncState)).U; IPEndPoint e = ((UdpState)(ar.AsyncState)).E; receivedBytes = u.EndReceive(ar, ref e); //int currentProtocol = (int) numero; //ResetSignal = reset > 0; //Console.WriteLine("Received: " + currentProtocol); MessageReceived = true; } C++ Code for sending data:
float indiceFloat[1]; indiceFloat[0] = indice_protocolo_actual; sender->setBuffer((void *)indiceFloat, sizeof(indiceFloat)); sender->sync(); sync method on J_Enviar (sender) class:
void J_Enviar::sync( void ) { if(!_initialized) init(); if( _buffer == 0L ) { fprintf( stderr, "Broadcaster::sync() - No buffer\n" ); return; } #if defined (WIN32) && !defined(__CYGWIN__) unsigned int size = sizeof( SOCKADDR_IN ); sendto( _so, (const char *)_buffer, _buffer_size, 0, (struct sockaddr *)&saddr, size ); int err = WSAGetLastError (); if (err!=0) fprintf( stderr, "Broadcaster::sync() - error %d\n",err ); #else unsigned int size = sizeof( struct sockaddr_in ); sendto( _so, (const void *)_buffer, _buffer_size, 0, (struct sockaddr *)&saddr, size ); #endif } Providing full SocketManager code for Receiving C# end:
using System; using System.Net; using System.Net.Sockets; namespace WpfApplication1 { public class SocketManager { private static SocketManager _instance = null; static readonly object Padlock = new object(); private IPEndPoint E; private UdpClient U; private UdpState S; private byte[] receivedBytes; public static bool MessageReceived = true; private SocketManager() { } public byte[] ReceivedBytes { get { return receivedBytes; } } public static SocketManager Instance { get { lock(Padlock) { return _instance ?? (_instance = new SocketManager()); } } } public void CreateReceivingSocket(IPAddress a, int puerto) { if(E==null || (E.Address != a && E.Port != puerto)) { E = new IPEndPoint(a, puerto); U = new UdpClient(puerto); S = new UdpState { E = E, U = U }; } } public void ReceiveCallback(IAsyncResult ar) { UdpClient u = ((UdpState)(ar.AsyncState)).U; IPEndPoint e = ((UdpState)(ar.AsyncState)).E; receivedBytes = u.EndReceive(ar, ref e); //int currentProtocol = (int) numero; //ResetSignal = reset > 0; //Console.WriteLine("Received: " + currentProtocol); MessageReceived = true; } public void RecibeDatos() { if (MessageReceived && U != null && S != null) { MessageReceived = false; //Console.WriteLine("listening for messages"); U.BeginReceive(ReceiveCallback, S); } } public void CloseConnection() { if (E != null) { E.Port = 5502; E = null; } if (U != null) U.Close(); } } public class UdpState { public IPEndPoint E; public UdpClient U; } } And this is my dispatchertimerclick which makes the program receive each 10 ms:
_dispatcherTimer.Tick += DispatcherTimerTick; _dispatcherTimer.Interval = new TimeSpan(0, 0, 0, 0, 1); _dispatcherTimer.Start(); private void DispatcherTimerTick(object sender, EventArgs e) { _exp1Class.sendData(); _sm.RecibeDatos(); byte[] recibidos = _sm.ReceivedBytes; if (recibidos != null) { float numero = BitConverter.ToSingle(recibidos, 0); _exp1Class.CurrentProtocol = (int) numero; } }