生活随笔
收集整理的這篇文章主要介紹了
C#UDP通讯UdpClient
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
目錄(?)[+]
遇到如下兩個問題 遠程主機強迫關閉了一個現有的連接的錯誤
[html] view plaincopy print?
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??????????????{??????????????}????????????}??????}//循環接收數據??}?? 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{}}}//循環接收數據}
遇到如下兩個問題
[html] view plaincopy print?
1.UdpListenClient.Receive接受數據位阻塞模式,一直等待對方的返回,網上詢問這個問題的很多,解答的卻很多答非所問,仔細查看了UdpClient?類發現里面有一個Socket熟悉,?? 1.UdpListenClient.Receive接受數據位阻塞模式,一直等待對方的返回,網上詢問這個問題的很多,解答的卻很多答非所問,仔細查看了UdpClient 類發現里面有一個Socket熟悉,
[html] view plaincopy print?
關于通訊的底層問題都通過該熟悉來設置,該熟悉又設置發送或者接受超時的設置,如?? 關于通訊的底層問題都通過該熟悉來設置,該熟悉又設置發送或者接受超時的設置,如
[html] view plaincopy print?
UdpListenClient.Client.ReceiveTimeout?=?3000;//設置超時接收返回?? UdpListenClient.Client.ReceiveTimeout = 3000;//設置超時接收返回
[html] view plaincopy print?
2.udp通訊發現有時會產生<h2><a?name="t1"></a><a?class="singleposttitle"?id="ctl01_TitleUrl"?href="http://www.cnblogs.com/zhuangxuqiang/archive/2009/04/17/1437926.html">遠程主機強迫關閉了一個現有的連接</a>的錯誤</h2><p>網上查找了很多,終于看到一篇</p><div?id="cnblogs_post_body"><p>在公司一項目的UDP消息服務開發中時不時的會遇到這樣一個問題:在UDP通信過程中,如果客戶端中途斷開,服務器會收到一個SocketException,錯誤ID為10054,描述是“遠程主機強迫關閉了一個現有的連接”,緊接著的事就可怕了,UDP服務終止監聽,所有客戶端都受到了影響。也就是說一個客戶端引起的異常導致了整個系統的崩潰。這個問題可是太嚴重了。</p><p>地球人都知道,UDP是無連接的,怎么會出現這個異常呢?百度了一圈,發現有這個問題的現象還不少,可就是沒有一個有效的回復。再GOOGLE一圈,有點眉目了。找到了一個微軟的解釋和一個DOTNET的解決方法:</p><p>微軟的解釋:<a?href="http://support.microsoft.com/kb/263823"><span?style="color:#0000ff;">http://support.microsoft.com/kb/263823</span></a></p><p>DOTNET的處理方法:<a?href="http://www.devnewsgroups.net/group/microsoft.public.dotnet.framework/topic1887.aspx"><span?style="color:#0000ff;">http://www.devnewsgroups.net/group/microsoft.public.dotnet.framework/topic1887.aspx</span></a></p><p>不過處理方法似乎對參數的設置不太正確:??byte[]?optionInValue?=?{?Convert.ToByte(true)?};??byte[]?optionOutValue;</p><p>按照這樣設置還是會拋出該異常。??首先,根據微軟的解釋,optionInValue?傳入的應該是false,而不是true;??其次,根據微軟的解釋,optionOutValue應該是一個DWORD值,不應不賦值,或設為null。</p><p>根據以上兩點,將以上兩句改為:??byte[]?optionInValue?=?{?Convert.ToByte(false)?};??byte[]?optionOutValue?=?new?byte[4];</p><p>經過<a?title="軟件測試知識庫"?class="replace_word"?style="color:#df3434;?font-weight:bold;"?href="http://lib.csdn.net/base/softwaretest"?target="_blank">測試</a>,模擬500個用戶進行登錄、收發消息、注銷、異常退出、再連接,均沒有再拋出該異常。服務表現穩定。</p></div><p>?</p>?? 2.udp通訊發現有時會產生
遠程主機強迫關閉了一個現有的連接的錯誤
網上查找了很多,終于看到一篇
在公司一項目的UDP消息服務開發中時不時的會遇到這樣一個問題:在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個用戶進行登錄、收發消息、注銷、異常退出、再連接,均沒有再拋出該異常。服務表現穩定。
?
總結
以上是生活随笔為你收集整理的C#UDP通讯UdpClient的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。