1. 程式人生 > >[Socket網路程式設計]一個封鎖操作被對 WSACancelBlockingCall 的呼叫中斷。

[Socket網路程式設計]一個封鎖操作被對 WSACancelBlockingCall 的呼叫中斷。

原文地址:http://www.cnblogs.com/xiwang/archive/2012/10/25/2740114.html記錄在此,方便查閱。

C#中在使用UDPClient迴圈監聽埠,在斷開UPDClient的時候,使用try...catch捕獲了異常,System.NET.Sockets.SocketException“一個封鎖操作被對 WSACancelBlockingCall 的呼叫中斷”,ErrorCode=10004。

      接收時的程式碼如下:

複製程式碼 複製程式碼
IPEndPoint ipendpoint = new IPEndPoint(IPAddress.Any, 0);
            Thread thread = new Thread(() =>
                    {
                        while (!m_StopListen)
                        {
                            try
                            {
                                if (m_udpClient.Client == null) return;
                                byte[] bytes = m_udpClient.Receive(ref ipendpoint);

                                string str = Encoding.Default.GetString(bytes);
                                Console.WriteLine(string.Format("接收的資料是: {0},來自IP:{1} ,埠 : {2}", str, ipendpoint.Address.ToString(), ipendpoint.Port));

                            }
                            catch (Exception ex)
                            {
                                Console.WriteLine(ex.Message);
                            }
                            Thread.Sleep(100);
                        }
                    });
            thread.IsBackground = true;
            thread.Start();
複製程式碼 複製程式碼

 

       停止監聽的程式碼:

            this.m_StopListen = true;
            m_udpClient.Close();
            m_udpClient = null;

       解決辦法:

      在開始呼叫UDPClient的Receive方法之前對UDPClient.Available屬性進行判斷,當Available屬性大於0時才開始從緩衝區讀取網路資料:

 

複製程式碼 複製程式碼
                            try
                            {
                                if (m_udpClient.Available <= 0) continue; 
                                if (m_udpClient.Client == null) return;
                                byte[] bytes = m_udpClient.Receive(ref ipendpoint);

                                string str = Encoding.Default.GetString(bytes);
                                Console.WriteLine(string.Format("接收的資料是: {0},來自IP:{1} ,埠 : {2}", str, ipendpoint.Address.ToString(), ipendpoint.Port));

                            }
複製程式碼 複製程式碼

 

       原因:MSDN對Available的解釋是:

      “Available 屬性用於確定在網路緩衝區中排隊等待讀取的資料的量。 如果資料可用,可呼叫 Read 獲取資料。 如果無資料可用,則 Available 屬性返回 0。

    如果遠端主機處於關機狀態或關閉了連線,則 Available 屬性將引發SocketException。如果遠端主機處於關機狀態或關閉了連線,則 Available 屬性將引發SocketException”。

           也就是說,錯誤的原因在於,但呼叫Close後,執行緒恰好繼續向網路緩衝區中讀取資料,所以引發SocketException。

     

  • 部落格地址:http://www.cnblogs.com/wolf-sun/ 
    部落格版權:如果文中有不妥或者錯誤的地方還望高手的你指出,以免誤人子弟。如果覺得本文對你有所幫助不如【推薦】一下!如果你有更好的建議,不如留言一起討論,共同進步! 再次感謝您耐心的讀完本篇文章。

原文地址:http://www.cnblogs.com/xiwang/archive/2012/10/25/2740114.html記錄在此,方便查閱。

C#中在使用UDPClient迴圈監聽埠,在斷開UPDClient的時候,使用try...catch捕獲了異常,System.NET.Sockets.SocketException“一個封鎖操作被對 WSACancelBlockingCall 的呼叫中斷”,ErrorCode=10004。

      接收時的程式碼如下:

複製程式碼 複製程式碼
IPEndPoint ipendpoint = new IPEndPoint(IPAddress.Any, 0);
            Thread thread = new Thread(() =>
                    {
                        while (!m_StopListen)
                        {
                            try
                            {
                                if (m_udpClient.Client == null) return;
                                byte[] bytes = m_udpClient.Receive(ref ipendpoint);

                                string str = Encoding.Default.GetString(bytes);
                                Console.WriteLine(string.Format("接收的資料是: {0},來自IP:{1} ,埠 : {2}", str, ipendpoint.Address.ToString(), ipendpoint.Port));

                            }
                            catch (Exception ex)
                            {
                                Console.WriteLine(ex.Message);
                            }
                            Thread.Sleep(100);
                        }
                    });
            thread.IsBackground = true;
            thread.Start();
複製程式碼 複製程式碼

 

       停止監聽的程式碼:

            this.m_StopListen = true;
            m_udpClient.Close();
            m_udpClient = null;

       解決辦法:

      在開始呼叫UDPClient的Receive方法之前對UDPClient.Available屬性進行判斷,當Available屬性大於0時才開始從緩衝區讀取網路資料:

 

複製程式碼 複製程式碼
                            try
                            {
                                if (m_udpClient.Available <= 0) continue; 
                                if (m_udpClient.Client == null) return;
                                byte[] bytes = m_udpClient.Receive(ref ipendpoint);

                                string str = Encoding.Default.GetString(bytes);
                                Console.WriteLine(string.Format("接收的資料是: {0},來自IP:{1} ,埠 : {2}", str, ipendpoint.Address.ToString(), ipendpoint.Port));

                            }
複製程式碼 複製程式碼

 

       原因:MSDN對Available的解釋是:

      “Available 屬性用於確定在網路緩衝區中排隊等待讀取的資料的量。 如果資料可用,可呼叫 Read 獲取資料。 如果無資料可用,則 Available 屬性返回 0。

    如果遠端主機處於關機狀態或關閉了連線,則 Available 屬性將引發SocketException。如果遠端主機處於關機狀態或關閉了連線,則 Available 屬性將引發SocketException”。

           也就是說,錯誤的原因在於,但呼叫Close後,執行緒恰好繼續向網路緩衝區中讀取資料,所以引發SocketException。