日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > C# >内容正文

C#

C#UDP通讯UdpClient

發(fā)布時(shí)間:2023/12/18 C# 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C#UDP通讯UdpClient 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

目錄(?)[+]

  • 遇到如下兩個(gè)問題
  • 遠(yuǎn)程主機(jī)強(qiáng)迫關(guān)閉了一個(gè)現(xiàn)有的連接的錯(cuò)誤
  • [html] view plaincopy print?
  • class?UdpClientClass??
  • {??
  • ????///?<summary>??
  • ????///?構(gòu)建客戶端??
  • ????///?</summary>??
  • ????///?<param?name="servierIpAddress">服務(wù)器iP地址或者域名</param>??
  • ????///?<param?name="sevierPort">服務(wù)器監(jiān)聽端口</param>??
  • ????///?<param?name="locadPort">本地監(jiān)聽端口</param>??
  • ????///?<param?name="timeOut">超時(shí)等待時(shí)間</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發(fā)送類,綁定了一個(gè)固定的端口??
  • ????///?</summary>??
  • ????private?static?UdpClient?UdpListenClient;??
  • ??
  • ????public?event?EventHandler?MessageChanged;??
  • ??
  • ????///?<summary>??
  • ????///?接收到服務(wù)器消息改變后觸發(fā)的事件??
  • ????///?</summary>??
  • ????///?<param?name="user"></param>??
  • ????public?void?OnMessageChanged(UdpClientClass?fp)??
  • ????{??
  • ????????if?(MessageChanged?!=?null)??
  • ????????{??
  • ????????????MessageChanged(fp,?null);??
  • ????????}??
  • ????}??
  • ??
  • ????///?<summary>??
  • ????///?服務(wù)器端的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));//啟動(dòng)新線程做接收??
  • ????????ClientRecThread.IsBackground?=?true;??
  • ????????ClientRecThread.Start();??
  • ??
  • ????}//啟動(dòng)并且?監(jiān)聽?服務(wù)器發(fā)來的數(shù)據(jù)??
  • ??
  • ??
  • ????private?void?RecF()//接收數(shù)據(jù)做服務(wù)??
  • ????{??
  • ????????byte[]?btRec?=?null;??
  • ????????while?(IsReceiving)??
  • ????????{??
  • ????????????IPEndPoint?remoteIPE?=?new?IPEndPoint(IPAddress.Any,?0);??
  • ????????????btRec?=?UdpListenClient.Receive(ref?remoteIPE);//UDP接收數(shù)據(jù)??
  • ????????????if?(btRec.Length?>?0?&&?remoteIPE.Address?==?ServerIPE.Address)//只處理特定的服務(wù)端的數(shù)據(jù)??
  • ????????????{??
  • ????????????????System.Windows.Forms.MessageBox.Show("res");??
  • ????????????}??
  • ????????????else??
  • ????????????{??
  • ????????????}??
  • ??
  • ????????}??
  • ????}//循環(huán)接收數(shù)據(jù)??
  • }??
  • class UdpClientClass{/// <summary>/// 構(gòu)建客戶端/// </summary>/// <param name="servierIpAddress">服務(wù)器iP地址或者域名</param>/// <param name="sevierPort">服務(wù)器監(jiān)聽端口</param>/// <param name="locadPort">本地監(jiān)聽端口</param>/// <param name="timeOut">超時(shí)等待時(shí)間</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發(fā)送類,綁定了一個(gè)固定的端口/// </summary>private static UdpClient UdpListenClient;public event EventHandler MessageChanged;/// <summary>/// 接收到服務(wù)器消息改變后觸發(fā)的事件/// </summary>/// <param name="user"></param>public void OnMessageChanged(UdpClientClass fp){if (MessageChanged != null){MessageChanged(fp, null);}}/// <summary>/// 服務(wù)器端的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));//啟動(dòng)新線程做接收ClientRecThread.IsBackground = true;ClientRecThread.Start();}//啟動(dòng)并且 監(jiān)聽 服務(wù)器發(fā)來的數(shù)據(jù)private void RecF()//接收數(shù)據(jù)做服務(wù){(diào)byte[] btRec = null;while (IsReceiving){IPEndPoint remoteIPE = new IPEndPoint(IPAddress.Any, 0);btRec = UdpListenClient.Receive(ref remoteIPE);//UDP接收數(shù)據(jù)if (btRec.Length > 0 && remoteIPE.Address == ServerIPE.Address)//只處理特定的服務(wù)端的數(shù)據(jù){System.Windows.Forms.MessageBox.Show("res");}else{}}}//循環(huán)接收數(shù)據(jù)}

    遇到如下兩個(gè)問題

    [html] view plaincopy print?
  • 1.UdpListenClient.Receive接受數(shù)據(jù)位阻塞模式,一直等待對方的返回,網(wǎng)上詢問這個(gè)問題的很多,解答的卻很多答非所問,仔細(xì)查看了UdpClient?類發(fā)現(xiàn)里面有一個(gè)Socket熟悉,??
  • 1.UdpListenClient.Receive接受數(shù)據(jù)位阻塞模式,一直等待對方的返回,網(wǎng)上詢問這個(gè)問題的很多,解答的卻很多答非所問,仔細(xì)查看了UdpClient 類發(fā)現(xiàn)里面有一個(gè)Socket熟悉, [html] view plaincopy print?
  • 關(guān)于通訊的底層問題都通過該熟悉來設(shè)置,該熟悉又設(shè)置發(fā)送或者接受超時(shí)的設(shè)置,如??
  • 關(guān)于通訊的底層問題都通過該熟悉來設(shè)置,該熟悉又設(shè)置發(fā)送或者接受超時(shí)的設(shè)置,如 [html] view plaincopy print?
  • UdpListenClient.Client.ReceiveTimeout?=?3000;//設(shè)置超時(shí)接收返回??
  • UdpListenClient.Client.ReceiveTimeout = 3000;//設(shè)置超時(shí)接收返回 [html] view plaincopy print?
  • 2.udp通訊發(fā)現(xiàn)有時(shí)會(huì)產(chǎn)生<h2><a?name="t1"></a><a?class="singleposttitle"?id="ctl01_TitleUrl"?href="http://www.cnblogs.com/zhuangxuqiang/archive/2009/04/17/1437926.html">遠(yuǎn)程主機(jī)強(qiáng)迫關(guān)閉了一個(gè)現(xiàn)有的連接</a>的錯(cuò)誤</h2><p>網(wǎng)上查找了很多,終于看到一篇</p><div?id="cnblogs_post_body"><p>在公司一項(xiàng)目的UDP消息服務(wù)開發(fā)中時(shí)不時(shí)的會(huì)遇到這樣一個(gè)問題:在UDP通信過程中,如果客戶端中途斷開,服務(wù)器會(huì)收到一個(gè)SocketException,錯(cuò)誤ID為10054,描述是“遠(yuǎn)程主機(jī)強(qiáng)迫關(guān)閉了一個(gè)現(xiàn)有的連接”,緊接著的事就可怕了,UDP服務(wù)終止監(jiān)聽,所有客戶端都受到了影響。也就是說一個(gè)客戶端引起的異常導(dǎo)致了整個(gè)系統(tǒng)的崩潰。這個(gè)問題可是太嚴(yán)重了。</p><p>地球人都知道,UDP是無連接的,怎么會(huì)出現(xiàn)這個(gè)異常呢?百度了一圈,發(fā)現(xiàn)有這個(gè)問題的現(xiàn)象還不少,可就是沒有一個(gè)有效的回復(fù)。再GOOGLE一圈,有點(diǎn)眉目了。找到了一個(gè)微軟的解釋和一個(gè)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>不過處理方法似乎對參數(shù)的設(shè)置不太正確:??
  • byte[]?optionInValue?=?{?Convert.ToByte(true)?};??
  • byte[]?optionOutValue;</p><p>按照這樣設(shè)置還是會(huì)拋出該異常。??
  • 首先,根據(jù)微軟的解釋,optionInValue?傳入的應(yīng)該是false,而不是true;??
  • 其次,根據(jù)微軟的解釋,optionOutValue應(yīng)該是一個(gè)DWORD值,不應(yīng)不賦值,或設(shè)為null。</p><p>根據(jù)以上兩點(diǎn),將以上兩句改為:??
  • byte[]?optionInValue?=?{?Convert.ToByte(false)?};??
  • byte[]?optionOutValue?=?new?byte[4];</p><p>經(jīng)過<a?title="軟件測試知識庫"?class="replace_word"?style="color:#df3434;?font-weight:bold;"?href="http://lib.csdn.net/base/softwaretest"?target="_blank">測試</a>,模擬500個(gè)用戶進(jìn)行登錄、收發(fā)消息、注銷、異常退出、再連接,均沒有再拋出該異常。服務(wù)表現(xiàn)穩(wěn)定。</p></div><p>?</p>??
  • 2.udp通訊發(fā)現(xiàn)有時(shí)會(huì)產(chǎn)生

    遠(yuǎn)程主機(jī)強(qiáng)迫關(guān)閉了一個(gè)現(xiàn)有的連接的錯(cuò)誤

    網(wǎng)上查找了很多,終于看到一篇

    在公司一項(xiàng)目的UDP消息服務(wù)開發(fā)中時(shí)不時(shí)的會(huì)遇到這樣一個(gè)問題:在UDP通信過程中,如果客戶端中途斷開,服務(wù)器會(huì)收到一個(gè)SocketException,錯(cuò)誤ID為10054,描述是“遠(yuǎn)程主機(jī)強(qiáng)迫關(guān)閉了一個(gè)現(xiàn)有的連接”,緊接著的事就可怕了,UDP服務(wù)終止監(jiān)聽,所有客戶端都受到了影響。也就是說一個(gè)客戶端引起的異常導(dǎo)致了整個(gè)系統(tǒng)的崩潰。這個(gè)問題可是太嚴(yán)重了。

    地球人都知道,UDP是無連接的,怎么會(huì)出現(xiàn)這個(gè)異常呢?百度了一圈,發(fā)現(xiàn)有這個(gè)問題的現(xiàn)象還不少,可就是沒有一個(gè)有效的回復(fù)。再GOOGLE一圈,有點(diǎn)眉目了。找到了一個(gè)微軟的解釋和一個(gè)DOTNET的解決方法:

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

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

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

    按照這樣設(shè)置還是會(huì)拋出該異常。 首先,根據(jù)微軟的解釋,optionInValue 傳入的應(yīng)該是false,而不是true; 其次,根據(jù)微軟的解釋,optionOutValue應(yīng)該是一個(gè)DWORD值,不應(yīng)不賦值,或設(shè)為null。

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

    經(jīng)過測試,模擬500個(gè)用戶進(jìn)行登錄、收發(fā)消息、注銷、異常退出、再連接,均沒有再拋出該異常。服務(wù)表現(xiàn)穩(wěn)定。

    ?

    總結(jié)

    以上是生活随笔為你收集整理的C#UDP通讯UdpClient的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。