Could you help me to get rid of this exception:
System.Net.Sockets.SocketException: "A blocking operation was interrupted by a call to WSACancelBlockingCall"
What the below code does: sends UDP message to the server and fetches reply (NAK or ACK)
Code that throws exception: m_receiveBytes = m_receiver.Receive(ref m_from);
Code:
public partial class _Default : System.Web.UI.Page
{
static readonly object lockScheduleIem = new object();
IPAddress m_AddressSend;
IPAddress m_AddressRecieve;
int m_groupPortSend;
int m_groupPortReceive;
IPEndPoint m_IPAddressSend;
IPEndPoint m_IPAddressReceive;
Byte[] m_receiveBytes;
Thread m_thread;
UdpClient m_receiver;
ManualResetEvent m_mre;
UdpClient m_sender;
IPEndPoint m_from;
protected void Page_Init(object sender, EventArgs e)
{
m_AddressSend = IPAddress.Parse("10.43.60.177");
m_AddressRecieve = IPAddress.Parse("10.43.60.99");
int.TryParse("60200", out m_groupPortSend);
int.TryParse("206", out m_groupPortReceive);
m_IPAddressSend = new IPEndPoint(m_AddressSend, m_groupPortSend);
m_IPAddressReceive = new IPEndPoint(m_AddressRecieve, m_groupPortReceive);
m_mre = new ManualResetEvent(false);
m_from = new IPEndPoint(IPAddress.Any, 0);
}
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Button1_Click(object sender, EventArgs e)
{
try
{
TimeSpan timeout;
timeout = new TimeSpan(0, 0, 0, 0, 5000);
m_sender = new UdpClient();
m_receiveBytes = null;
m_receiver = new UdpClient(m_IPAddressReceive);
m_thread = new Thread(new ThreadStart(ThreadProc));
m_thread.Start();
string str = string.Empty;
using (StreamReader sr = new StreamReader(@"C:\UDPmsgArchive\UDPmsg_Of_2011_10_18_13_7_33_968_634545400539687500.xml"))
str = sr.ReadToEnd();
byte[] XMLbytes = Encoding.ASCII.GetBytes(str);
m_sender.Send(XMLbytes, XMLbytes.Length, m_IPAddressSend);
m_mre.WaitOne(timeout, true);
m_mre.Reset();
m_receiver.Close();
if (m_receiveBytes != null)
Response.Write(Encoding.ASCII.GetString(m_receiveBytes, 0, m_receiveBytes.Length));
else
Response.Write("string.Empty");
}
catch (Exception ex)
{
Response.Write(ex.ToString());
}
}
public void ThreadProc()
{
try
{
m_receiveBytes = m_receiver.Receive(ref m_from); // ERROR HERE
m_mre.Set();
m_receiver.Close();
}
finally
{
m_mre.Set();
}
}
}
If I'm reading your code right, you're starting a thread to receive a UDP message. If it receives the message, it sets an event. The main thread starts the thread and then waits up to five seconds for the event to be set. If the event isn't set within that time, the main thread destroys the receiver that the thread is waiting on.
That's definitely going to throw an exception.
If you wait to eliminate the exception, modify your ThreadProc
try
{
// do stuff here
}
catch (SocketException) // or whatever the exception is that you're getting
{
}
I would suggest that you not include the m_mre.Set()
call in a finally
section. The main thread calls Reset
on the event after the wait has completed, whether or not there is a timeout. If the thread calls Set
in the finally, the the event's state will be set if a timeout occurs, because the following happens:
main thread calls Reset()
main thread calls Close() on the client
ThreadProc calls Set() in the finally
Instead, change your main thread code to look like this:
if (m_mre.WaitOne(timeout, true))
{
// event was set by the thread proc
// process the received data
// and reset the event
m_mre.Reset();
}
else
{
// A timeout occurred.
// Close the receiver
m_receiver.Close();
}
That said, you really don't have to spin up a thread to do this. Rather, you could use the asynchronous capabilities of UdpClient
. Something like:
// Set timeout on the socket
m_receiver.Client.ReceiveTimeout = 5000;
try
{
IAsyncResult ir = m_receiver.BeginReceive(null, null);
m_receivedBytes = m_receiver.EndReceive(ir, m_receiver.Client.RemoteEndPoint);
// process received bytes here
}
catch (SocketException)
{
// Timeout or some other error happened.
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With