你能帮助我摆脱这个例外:
System.Net.Sockets.SocketException:“阻塞操作是 被WSACancelBlockingCall调用打断“
以下代码的作用:将UDP消息发送到服务器并获取回复 (NAK或ACK)
引发异常的代码:m_receiveBytes = m_receiver.Receive(ref m_from);
代码:
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();
}
}
}
答案 0 :(得分:4)
如果我正在读你的代码,那么你就开始接收一条UDP消息。如果它收到消息,则设置一个事件。主线程启动线程,然后等待最多五秒钟来设置事件。如果事件未在该时间内设置,则主线程会销毁线程正在等待的接收器。
这肯定会引发异常。
如果您等待消除例外,请修改ThreadProc
try
{
// do stuff here
}
catch (SocketException) // or whatever the exception is that you're getting
{
}
我建议您不在m_mre.Set()
部分中加入finally
来电。无论是否存在超时,主线程在等待完成后对事件调用Reset
。如果线程在finally中调用Set
,则在发生超时时将设置事件的状态,因为发生以下情况:
main thread calls Reset()
main thread calls Close() on the client
ThreadProc calls Set() in the finally
相反,请将主线程代码更改为:
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();
}
那就是说,你真的没有必要通过一个线程来做这件事。相反,您可以使用UdpClient
的异步功能。类似的东西:
// 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.
}