一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - ASP.NET教程 - .NET中應(yīng)用程序內(nèi)共享UdpClient聯(lián)機(jī)的實(shí)現(xiàn)方法

.NET中應(yīng)用程序內(nèi)共享UdpClient聯(lián)機(jī)的實(shí)現(xiàn)方法

2019-11-06 10:31asp.net教程網(wǎng) ASP.NET教程

本篇文章介紹了,.NET中應(yīng)用程序內(nèi)共享UdpClient聯(lián)機(jī)的實(shí)現(xiàn)方法。需要的朋友參考下

.NET中應(yīng)用程序內(nèi)共享UdpClient聯(lián)機(jī)的實(shí)現(xiàn)方法

 

在開發(fā)與遠(yuǎn)程設(shè)備通訊的系統(tǒng)時(shí),為了提高數(shù)據(jù)傳輸?shù)男剩3x擇UDP這個通訊協(xié)議來作為數(shù)據(jù)傳輸?shù)拿浇椤6?.NET framework中所提供的UdpClient對象,可以幫助開發(fā)人員依照系統(tǒng)需求開啟UDP套接字點(diǎn),快速建立UDP聯(lián)機(jī)來提供與遠(yuǎn)程設(shè)備通訊的功能。

 

.NET中應(yīng)用程序內(nèi)共享UdpClient聯(lián)機(jī)的實(shí)現(xiàn)方法

 

這個系統(tǒng)架構(gòu)下當(dāng)增加一個不同種類的遠(yuǎn)程設(shè)備時(shí),必須要提供一個不同的UDP套接字點(diǎn),才能用來提供與不同種類遠(yuǎn)程設(shè)備通訊的功能,在遠(yuǎn)程設(shè)備種類越來越多時(shí),系統(tǒng)所需要的UDP套接字點(diǎn)就會依照遠(yuǎn)程設(shè)備種類而增加。

 

.NET中應(yīng)用程序內(nèi)共享UdpClient聯(lián)機(jī)的實(shí)現(xiàn)方法

 

在遠(yuǎn)程設(shè)備種類越來越多的情景中,為了網(wǎng)絡(luò)管理考慮會限制系統(tǒng)與遠(yuǎn)程設(shè)備通訊時(shí),必須統(tǒng)一使用同一個UDP套接字點(diǎn)來與遠(yuǎn)程設(shè)備通訊,再由封包內(nèi)容、或是IP地址去判斷實(shí)際連接的遠(yuǎn)程設(shè)備為何。

復(fù)制代碼代碼如下:

class Program
{
    static void Main(string[] args)
    {
        // Receiver
        UdpClient udpClientA = new UdpClient(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 1234));

        UdpClient udpClientB = new UdpClient(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 1234));
    }
}


依照系統(tǒng)需求開發(fā)人員可能寫出上列的程序代碼,直接建立兩個UdpClient對象來開啟同一個UDP套接字點(diǎn)。這段程序代碼內(nèi)容可以通過編譯程序的檢查,但在按下執(zhí)行之后,就會在Visual Studio之中看到SocketException的例外通知,用來告知開發(fā)人員同一個套接字點(diǎn)只能被開啟一次,使用兩個UdpClient來開啟同一個套接字點(diǎn)是無法執(zhí)行的。

 

.NET中應(yīng)用程序內(nèi)共享UdpClient聯(lián)機(jī)的實(shí)現(xiàn)方法

 

有涉略過Design pattern的開發(fā)人員,在遇到資源對象只能有一個實(shí)體的情景,會想到套用Singleton Pattern來提供資源對象共享的功能。系統(tǒng)中UdpClient對象所開啟的UDP套接字點(diǎn),就是屬于這種只能由一個對象所開啟的資源,這個情景中在UdpClient對象上套用Singleton Pattern看起來會是個不錯的選擇。

復(fù)制代碼代碼如下:

class Program
{
    // Singleton
    private static UdpClient _udpClientInstance = null;

    private static UdpClient UdpClientInstance
    {
        get
        {
            if (_udpClientInstance == null)
            {
                _udpClientInstance = new UdpClient(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 1234));
            }
            return _udpClientInstance;
        }
    }

 
    // Main
    static void Main(string[] args)
    {
        // Receiver
        UdpClient udpClientA = Program.UdpClientInstance;

        UdpClient udpClientB = Program.UdpClientInstance;

        // Transmiter
        UdpClient transmiter = new UdpClient(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9999));

 
        // Send
        transmiter.Send(new byte[] { 55 }, 1, new IPEndPoint(IPAddress.Parse("127.0.0.1"), 1234));

 
        // Receive
        byte[] packet = null;
        IPEndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, IPEndPoint.MinPort);

        packet = udpClientA.Receive(ref remoteEndPoint);
        Console.WriteLine(string.Format("UdpClientA Receive:{0}", packet[0]));

        packet = udpClientB.Receive(ref remoteEndPoint);
        Console.WriteLine(string.Format("UdpClientB Receive:{0}", packet[0]));

        // End
        Console.ReadLine();

        // Close
        transmiter.Close();
        udpClientB.Close();
        udpClientA.Close();
    }
}

 

將Singleton Pattern套用在系統(tǒng)內(nèi)所使用的UdpClient物件上,可以寫出上列的程序代碼,系統(tǒng)內(nèi)所使用的UdpClient對象都是取用到系統(tǒng)內(nèi)一個靜態(tài)存放的共享UdpClient對象。這段程序代碼內(nèi)容可以通過編譯程序的檢查,并且在執(zhí)行時(shí)也不會出現(xiàn)SocketException的例外通知,因?yàn)樘子肧ingleton Pattern讓系統(tǒng)內(nèi)只會開啟UDP套接字點(diǎn)一次。

 

但進(jìn)階一點(diǎn)去思考UdpClient對象的封包接收功能,UdpClient對象中提供Receive方法來等待、接收遠(yuǎn)程設(shè)備傳送的數(shù)據(jù)封包,收到數(shù)據(jù)封包之后再次執(zhí)行Receive方法會繼續(xù)等待、接收下一個數(shù)據(jù)封包。也就是說一個遠(yuǎn)程設(shè)備傳送的數(shù)據(jù)封包,UdpClient只能透過Receive方法取得一次,在系統(tǒng)內(nèi)共享同UdpClient對象,沒有辦法共享Receive方法所取得的數(shù)據(jù)封包。

 

觀察上列范例的執(zhí)行結(jié)果,可以發(fā)現(xiàn)在范例中由transmiter所傳送的資料封包,在被UdpClientA透過Receive方法接收之后,UdpClientB無法接收到這個遠(yuǎn)程傳送的數(shù)據(jù)封包,這也就驗(yàn)證范例中將Singleton Pattern套用在系統(tǒng)內(nèi)所使用UdpClient上的方式,會發(fā)生了無法共享數(shù)據(jù)封包的問題。

 

.NET中應(yīng)用程序內(nèi)共享UdpClient聯(lián)機(jī)的實(shí)現(xiàn)方法

 

為了提供系統(tǒng)使用同一個UDP套接字點(diǎn)來與遠(yuǎn)程設(shè)備通訊,再由封包內(nèi)容、或是IP地址去判斷實(shí)際連接的遠(yuǎn)程設(shè)備為何的功能。筆者設(shè)計(jì)一個名為MutualUdpClient的解決方案,用來在系統(tǒng)內(nèi)共享UDP通訊聯(lián)機(jī)并且共享遠(yuǎn)程設(shè)備傳送的數(shù)據(jù)封包。

.NET中應(yīng)用程序內(nèi)共享UdpClient聯(lián)機(jī)的實(shí)現(xiàn)方法

 

在MutualUdpClient這個解決方案中,套用先前部落格中所發(fā)表的Singleton Pool模式,套用這個模式讓系統(tǒng)能夠共享UdpClient聯(lián)機(jī),并且在有系統(tǒng)對象使用UdpClient聯(lián)機(jī)時(shí)就開啟共享UDP通訊聯(lián)機(jī),而在所有系統(tǒng)對象都不需要使用UdpClient聯(lián)機(jī)才真正去關(guān)閉這個共享的UDP通訊聯(lián)機(jī)。

.NET中應(yīng)用程序內(nèi)共享UdpClient聯(lián)機(jī)的實(shí)現(xiàn)方法

 

套用Singleton Pool模式解決了共享UdpClient聯(lián)機(jī)的功能,接著在MutualUdpClient這個解決方案中,為了共享遠(yuǎn)程設(shè)備傳送的數(shù)據(jù)封包,在UdpClient與MutualUdpClient之間加入了一個RouteUdpClient對象。

 

RouteUdpClient對象是一個主動式的對象,在被建立之后會開啟一條獨(dú)立的線程,不斷的接收UdpClient所接收到的數(shù)據(jù)封包,并且將接收到數(shù)據(jù)封包透過事件的方式通知每個MutualUdpClient,經(jīng)由這樣的流程就可以將遠(yuǎn)程設(shè)備所傳送的數(shù)據(jù)封包,在每個MutualUdpClient之間共享。

 

而MutualUdpClient對象在收到RouteUdpClient所提供的數(shù)據(jù)封包時(shí),會先將數(shù)據(jù)封包暫存在一個隊(duì)列里,并且在MutualUdpClient對象的Receive方法被呼叫時(shí),再從隊(duì)列取出數(shù)據(jù)封包并且回傳給呼叫端,用以將遠(yuǎn)程設(shè)備傳送的數(shù)據(jù)封包提供給呼叫端做后續(xù)的處理。經(jīng)由這樣的方式,每個系統(tǒng)中所建立的MutualUdpClient對象就可以透過Receive方法取得,每個遠(yuǎn)程設(shè)備傳送的數(shù)據(jù)封包。

 

*這邊要特別一提的是,MutualUdpClient對象不選擇事件方式來提供數(shù)據(jù)封包而采用Receive方法來提供,是為了讓使用MutualUdpClient對象的開發(fā)人員,在使用對象的時(shí)候,能夠得到與使用UdpClient一樣的開發(fā)體驗(yàn),用以減少開發(fā)時(shí)的學(xué)習(xí)時(shí)間。

 

.NET中應(yīng)用程序內(nèi)共享UdpClient聯(lián)機(jī)的實(shí)現(xiàn)方法

 

處理完共享UdpClient聯(lián)機(jī)、共享遠(yuǎn)程設(shè)備傳送的資料封包之后,還要處理一下傳送數(shù)據(jù)封包到遠(yuǎn)程設(shè)備的功能。在MutualUdpClient之中,對于傳送數(shù)據(jù)封包到遠(yuǎn)程設(shè)備并沒有特殊需求,所以直接使用UdpClient的Send功能就可以完成將數(shù)據(jù)封包傳送到遠(yuǎn)程設(shè)備的功能。

復(fù)制代碼代碼如下:

class Program
{
    static void Main(string[] args)
    {
        // Receiver
        MutualUdpClient udpClientA = new MutualUdpClient(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 1234));

        MutualUdpClient udpClientB = new MutualUdpClient(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 1234));

        // Transmiter
        UdpClient transmiter = new UdpClient(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9999));

 
        // Send
        transmiter.Send(new byte[] { 55 }, 1, new IPEndPoint(IPAddress.Parse("127.0.0.1"), 1234));

 
        // Receive
        byte[] packet = null;
        IPEndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, IPEndPoint.MinPort);

        packet = udpClientA.Receive(ref remoteEndPoint);
        Console.WriteLine(string.Format("UdpClientA Receive:{0}", packet[0]));

        packet = udpClientB.Receive(ref remoteEndPoint);
        Console.WriteLine(string.Format("UdpClientB Receive:{0}", packet[0]));

        // End
        Console.ReadLine();

        // Close
        transmiter.Close();
        udpClientB.Close();
        udpClientA.Close();
    }
}


上列程序代碼示范如何在系統(tǒng)中使用MutualUdpClient對象,在范例中可以看到程序代碼中直接建立了兩個相同UDP端點(diǎn)的MutualUdpClient對象,并且可以正常的執(zhí)行不會出現(xiàn)SocketException的例外通知。而遠(yuǎn)程設(shè)備transmiter所傳送的數(shù)據(jù)封包,在被UdpClientA透過Receive方法接收之后,UdpClientB依然可以透過Receive方法接收同一個資料,這也就驗(yàn)證了MutualUdpClient對象提供了共享通訊聯(lián)機(jī)、共享數(shù)據(jù)封包的功能。

 

.NET中應(yīng)用程序內(nèi)共享UdpClient聯(lián)機(jī)的實(shí)現(xiàn)方法

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 精品久久久噜噜噜久久久app | 91亚洲精品丁香在线观看 | 好性20岁| 美女脱了内裤让男生玩屁股 | 国产最新精品视频 | 久久精品热在线观看85 | 门房秦大爷在线阅读 | 欧亚精品一区二区三区 | 国产精品视频一区二区三区不卡 | 我的妹妹最近有点怪在线观看 | 亚洲人成网站在线观看播放青青 | 亚洲国产在线观看免费视频 | 手机av影院 | 亚洲咪咪| 国产男女爱视频在线观看 | 国产在线精品观看 | 美女脱了内裤打开腿让人羞羞软件 | 喜马拉雅听书免费版 | 欧美日韩亚洲成人 | 无遮挡免费h肉动漫在线观看 | 九九99九九精彩 | 日本免费全黄一级裸片视频 | 朝鲜美女免费一级毛片 | 日本老头4569gay | 91久久综合 | 亚洲国产精品久久久久久 | 特黄未满14周岁毛片 | 超兴奋朋友的中文字幕下 | 1024亚洲精品国产 | 清纯漂亮女友初尝性过程 | 欧美a一级片 | 第一次做m被调教经历 | 99re视频精品全部免费 | 亚洲 欧美 国产 在线 日韩 | 亚洲六月丁香婷婷综合 | 美女天天操| 久久中文电影 | 欧美黑人成人免费全部 | 免费高清视频在线观看 | 精品夜夜澡人妻无码AV蜜桃 | 国语自产拍在线播放不卡 |