2011-10-24 38 views
5

你能幫我擺脫這個異常:如何停止SocketException:拋出阻塞操作被調用WSACancelBlockingCall中斷?

System.Net.Sockets.SocketException: 「截止動作是 通過調用中斷WSACancelBlockingCall」

  1. 什麼下面的代碼的作用:發送UDP消息發送到服務器,並獲取應答 (NAK或ACK)

  2. 代碼拋出異常: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(); 
     } 
    } 
} 

回答

4

如果我在讀你的代碼的權利,你開始一個線程接收UDP報文。如果它收到消息,它會設置一個事件。主線程啓動線程,然後等待五秒鐘以便設置事件。如果在該時間內沒有設置事件,則主線程銷燬線程正在等待的接收器

這絕對會引發異常。

如果等待消除異常,修改ThreadProc

try 
{ 
    // do stuff here 
} 
catch (SocketException) // or whatever the exception is that you're getting 
{ 
} 

我建議你包括在finally部分m_mre.Set()電話。主線程在等待完成後調用事件Reset,無論是否超時。如果線程調用的最後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. 
} 
+0

真的很感激,我會嘗試你的建議,我給你反饋 – user852194

+0

嗨吉姆我嘗試下面的邏輯可惜還是有相同的錯誤。 – user852194

+0

@ user852194:您收到的確切例外是什麼? 「catch」實際上是否捕捉到異常? –

相關問題