你能帮我摆脱这个例外:
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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果我没看错你的代码,那么你正在启动一个线程来接收 UDP 消息。如果它收到消息,就会设置一个事件。主线程启动线程,然后等待最多五秒钟以设置事件。如果在该时间内未设置事件,则主线程将销毁该线程正在等待的接收器。
这肯定会抛出异常。
如果您等待消除异常,请修改您的ThreadProc
try
{
// do stuff here
}
catch (SocketException) // or whatever the exception is that you're getting
{
}
Run Code Online (Sandbox Code Playgroud)
我建议您不要将调用包含m_mre.Set()在一个finally部分中。主线程Reset在等待完成后调用该事件,无论是否超时。如果线程Set在finally中调用,如果发生超时,事件的状态将被设置,因为会发生以下情况:
main thread calls Reset()
main thread calls Close() on the client
ThreadProc calls Set() in the finally
Run Code Online (Sandbox Code Playgroud)
相反,将主线程代码更改为如下所示:
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();
}
Run Code Online (Sandbox Code Playgroud)
也就是说,您实际上不必启动线程来执行此操作。相反,您可以使用 的异步功能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.
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
21809 次 |
| 最近记录: |