C#UDP通訊UdpClient

來源:互聯網
上載者:User

 

    class UdpClientClass    {        /// <summary>        /// 構建用戶端        /// </summary>        /// <param name="servierIpAddress">伺服器iP地址或者網域名稱</param>        /// <param name="sevierPort">伺服器監聽連接埠</param>        /// <param name="locadPort">本地監聽連接埠</param>        /// <param name="timeOut">逾時等待時間</param>        public UdpClientClass(string servierIpAddress, int sevierPort, int locadPort, int timeOut)        {            if (FpHelper.CheckIpAddress(ref servierIpAddress) == true)            {                try                {                    ServerIPE = new IPEndPoint(IPAddress.Parse(servierIpAddress), sevierPort);                    UdpListenClient = new UdpClient(locadPort);//固定通訊連接埠                    UdpListenClient.Client.ReceiveTimeout = 3000;                    const long IOC_IN = 0x80000000;                    const long IOC_VENDOR = 0x18000000;                    const long SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12;                    byte[] optionInValue = { Convert.ToByte(false) };                    byte[] optionOutValue = new byte[4];                    UdpListenClient.Client.IOControl((IOControlCode)SIO_UDP_CONNRESET, optionInValue, optionOutValue);                                   }                catch (System.Exception ex)                {                    MessageBox.Show("綁定連接埠失敗" + ex.Message.ToString());                }            }        }        /// <summary>        /// UDP發送類,綁定了一個固定的連接埠        /// </summary>        private static UdpClient UdpListenClient;        public event EventHandler MessageChanged;        /// <summary>        /// 接收到伺服器訊息改變後觸發的事件        /// </summary>        /// <param name="user"></param>        public void OnMessageChanged(UdpClientClass fp)        {            if (MessageChanged != null)            {                MessageChanged(fp, null);            }        }        /// <summary>        /// 伺服器端的IP與連接埠        /// </summary>        private IPEndPoint ServerIPE = null;        bool IsReceiving = false;        public void Send(byte[] data, int len)        {          int len1 =  UdpListenClient.Send(data, len, ServerIPE);            if (!IsReceiving)                StartAndLsn();        }        private Thread ClientRecThread;        private void StartAndLsn()        {            IsReceiving = true;            ClientRecThread = new Thread(new ThreadStart(RecF));//啟動新線程做接收            ClientRecThread.IsBackground = true;            ClientRecThread.Start();        }//啟動並且 監聽 伺服器發來的資料        private void RecF()//接收資料做服務        {            byte[] btRec = null;            while (IsReceiving)            {                IPEndPoint remoteIPE = new IPEndPoint(IPAddress.Any, 0);                btRec = UdpListenClient.Receive(ref remoteIPE);//UDP接收資料                if (btRec.Length > 0 && remoteIPE.Address == ServerIPE.Address)//只處理特定的服務端的資料                {                    System.Windows.Forms.MessageBox.Show("res");                }                else                {                }            }        }//迴圈接收資料    }
遇到如下兩個問題
1.UdpListenClient.Receive接受資料位元阻塞模式,一直等待對方的返回,網上詢問這個問題的很多,解答的卻很多答非所問,仔細查看了UdpClient 類發現裡面有一個Socket熟悉,
關於通訊的底層問題都通過該熟悉來設定,該熟悉又設定發送或者接受逾時的設定,如
UdpListenClient.Client.ReceiveTimeout = 3000;//設定逾時接收返回
2.udp通訊發現有時會產生遠程主機強迫關閉了一個現有的串連的錯誤

網上尋找了很多,終於看到一篇

在公司一項目的UDPMessage Service開發中時不時的會遇到這樣一個問題:在UDP通訊過程中,如果用戶端中途斷開,伺服器會收到一個SocketException,錯誤ID為10054,描述是“遠程主機強迫關閉了一個現有的串連”,緊接著的事就可怕了,UDP服務終止監聽,所有用戶端都受到了影響。也就是說一個用戶端引起的異常導致了整個系統的崩潰。這個問題可是太嚴重了。

地球人都知道,UDP是不需連線的,怎麼會出現這個異常呢?百度了一圈,發現有這個問題的現象還不少,可就是沒有一個有效回複。再GOOGLE一圈,有點眉目了。找到了一個微軟的解釋和一個DOTNET的解決方案:

微軟的解釋:http://support.microsoft.com/kb/263823

DOTNET的處理方法:http://www.devnewsgroups.net/group/microsoft.public.dotnet.framework/topic1887.aspx

不過處理方法似乎對參數的設定不太正確:byte[] optionInValue = { Convert.ToByte(true) };byte[] optionOutValue;

按照這樣設定還是會拋出該異常。首先,根據微軟的解釋,optionInValue 傳入的應該是false,而不是true;其次,根據微軟的解釋,optionOutValue應該是一個DWORD值,不應不賦值,或設為null。

根據以上兩點,將以上兩句改為:byte[] optionInValue = { Convert.ToByte(false) };byte[] optionOutValue = new byte[4];

經過測試,類比500個使用者進行登入、收發訊息、登出、異常退出、再串連,均沒有再拋出該異常。服務表現穩定。

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.