Вызов UdpClient.Send() внутри события System.Timers.Timer не работает
В моем приложении я получаю поток UDP и пересылаю его на две другие конечные точки UDP. Моя проблема в том, что мне нужно поместить задержку между двумя потоками, поэтому я решил использовать таймер. Это мой код (где я показываю только соответствующие методы):
public void Start()
{
Socket udpSocket = m_udpLocalClient.Client;
udpSocket.ReceiveBufferSize = BUFFER_SIZE;
// Enable broadcast
udpSocket.SetSocketOption(SocketOptionLevel.Socket,
SocketOptionName.Broadcast,
1);
// Enable reusing address
udpSocket.SetSocketOption(SocketOptionLevel.Socket,
SocketOptionName.ReuseAddress,
true);
// Bind the socket to the local endpoint and listen for incoming connections.
udpSocket.Bind(new IPEndPoint(IPAddress.Any, m_ListenPort));
m_udpLocalClient.JoinMulticastGroup(IPAddress.Parse(m_ListenIP));
udpSocket.BeginReceiveFrom(m_data,
0,
m_data.Length,
SocketFlags.None,
ref m_ListenEndPoint,
new AsyncCallback(ReceiveData),
m_udpLocalClient);
}
public void TimerCallback(object sender, ElapsedEventArgs e)
{
byte[] Data = new byte[m_BytesReceived];
m_Timer.Stop();
m_Mutex.WaitOne();
m_Buffer.Get(Data);
m_Mutex.ReleaseMutex();
//Send Packets lo LocalHost EndPoint
m_udpLocalClient.Send(Data, Data.Length, m_LocalEndPoint);
}
void ReceiveData(IAsyncResult iar)
{
int recv = 0;
try
{
UdpClient udpReceiver = (UdpClient)iar.AsyncState;
recv = udpReceiver.Client.EndReceiveFrom(iar, ref m_ListenEndPoint);
if (recv == 0) return;
//Forward packets on the FwEndpoint
m_udpFwClient.Send(m_data, recv, m_FwEndPoint);
//Send Packets lo LocalHost EndPoint
//m_udpLocalClient.Send(m_data, recv, m_LocalEndPoint);
m_Mutex.WaitOne();
m_Buffer.Put(m_data);
m_Mutex.ReleaseMutex();
if (!m_Timer.Enabled) m_Timer.Start();
udpReceiver.Client.BeginReceiveFrom(m_data,
0,
m_data.Length,
SocketFlags.None,
ref m_ListenEndPoint,
new AsyncCallback(ReceiveData),
udpReceiver);
}
catch (Exception e)
{
//...handle....
}
}
НОТА. Член m_Buffer является CircularBuffer от CodePlex.
Проблема здесь в том, что вызов
m_udpLocalClient.Send(Data, Data.Length, m_LocalEndPoint);
в TimerCallBack, кажется, не имеет никакого эффекта, в то время как я раскомментирую тот же самый в ReceiveData, он работает.
Я также пытаюсь использовать асинхронный метод BeginSend(), но безуспешно. Где я не прав?
С Уважением,
Даниэла.
1 ответ
Я думаю, что, поскольку вы сразу возвращаетесь в состояние приема после получения некоторых данных, вам не разрешено отправлять данные с использованием того же сокета в обратном вызове таймера. В то время, когда таймер работает, вы уже сказали сокету подождать, пока поступят дополнительные данные.
Вам нужно будет использовать другой сокет /UdpClient для отправки данных в вашем обратном вызове таймера.