C# UDP網(wǎng)絡(luò)通信的實(shí)現(xiàn)示例
TCP和UDP基本概念
TCP:(Transmission Control Protocol)是一種面向連接、可靠的、基于字節(jié)流的傳輸層通信協(xié)議。并且提供了全雙工通信,允許倆個(gè)應(yīng)用直接建立一個(gè)可靠的連接以進(jìn)行數(shù)據(jù)交換/UDP:(User Datagram Protocol):是一種無(wú)連接、不可靠、基于數(shù)據(jù)報(bào)文傳輸層協(xié)議,它不提供數(shù)據(jù)包的分組。排序和組裝功能也不提供可靠性的保證
TCP和UDP區(qū)別
1.TCP是基于連接 而udp基于非連接
2.tcp傳輸數(shù)據(jù)穩(wěn)定可靠,適用于對(duì)網(wǎng)絡(luò)通信質(zhì)量要求高的場(chǎng)景,需要準(zhǔn)確無(wú)誤發(fā)給對(duì)方 例如 傳輸文件 發(fā)送郵件 瀏覽網(wǎng)頁(yè)
3.udp優(yōu)點(diǎn)是速度快,輕量級(jí)。但是有可能會(huì)產(chǎn)生丟包,所以適用于實(shí)時(shí)性要求較高的但是對(duì)丟包沒(méi)有要求太高場(chǎng)景,例如 域名查詢(xún) 語(yǔ)音通話 視頻直播等
UDP協(xié)議特點(diǎn)
1.udp基于IP的簡(jiǎn)單的協(xié)議,不可靠的協(xié)議
2.優(yōu)點(diǎn)就是簡(jiǎn)單 輕量化 傳輸速度高、要求可靠性不太高
3.缺點(diǎn):沒(méi)有流量控制,沒(méi)有應(yīng)答確認(rèn)機(jī)制。不能解決丟包重發(fā)錯(cuò)順序問(wèn)題
UDP使用場(chǎng)景
當(dāng)應(yīng)用程序?qū)鬏數(shù)目煽啃砸蟛桓撸菍?duì)傳輸速度和延遲要求較高時(shí)可以使用udp協(xié)議。例如語(yǔ)音和視頻聊天。主要在這些場(chǎng)景如果丟了一倆個(gè)數(shù)據(jù)包 不會(huì)產(chǎn)生太大的影響。
UDP服務(wù)器
控件
兩個(gè)按鈕(打開(kāi)服務(wù)器按鈕,發(fā)送消息按鈕),輸入框,文本框控件(RichTextBox:顯示聊天)
打開(kāi)服務(wù)器按鈕方法
創(chuàng)建全局變量 Socket
// 先講socket進(jìn)行客戶(hù)端和服務(wù)器的書(shū)寫(xiě) Socket socket; private void button1_Click(object sender, EventArgs e) { //參數(shù)1 ip地址類(lèi)型 ipv4的類(lèi)型 //參數(shù)2 傳遞數(shù)據(jù)類(lèi)型 數(shù)據(jù)報(bào)文類(lèi)型 //參數(shù)3 協(xié)議類(lèi)型 udp協(xié)議 //1 創(chuàng)建socket套接字作為服務(wù)器對(duì)象 socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); // 2綁定ip和端口 IPAddress iPAddress = IPAddress.Parse("192.168.107.83"); socket.Bind(new IPEndPoint(iPAddress,8081)); //3 接受消息 startReceive(); } void startReceive() { //創(chuàng)建線程 開(kāi)啟線程 new Thread(() => { byte[] body = new byte[1024]; while (true) { int count = socket.Receive(body); //接受數(shù)據(jù) string s = Encoding.UTF8.GetString(body, 0, count); richTextBox1.Invoke((Action)(() => { richTextBox1.AppendText(s + "\t\n"); richTextBox1.SelectionStart=richTextBox1.Text.Length; richTextBox1.ScrollToCaret(); })); } }).Start() ; }
發(fā)送消息事件
//發(fā)消息的方法 給指定的人發(fā)消息 string[] ips = new string[] {"192.168.107.83", }; private void button2_Click(object sender, EventArgs e) { socket.SendTo(Encoding.UTF8.GetBytes(this.textBox1.Text), new IPEndPoint(IPAddress.Parse("192.168.107.83"), 8082) ); }
UDP客戶(hù)端
控件
三個(gè)按鈕(打開(kāi),發(fā)送,關(guān)閉),RichTextBox(顯示聊天)
public Form1() { InitializeComponent(); } void f1() { byte[] body = new byte[1024]; while (true) { int count = socket.Receive(body); //接受數(shù)據(jù) string s = Encoding.UTF8.GetString(body, 0, count); richTextBox1.Invoke((Action)(() => { richTextBox1.AppendText(s + "\t\n"); richTextBox1.SelectionStart = richTextBox1.Text.Length; richTextBox1.ScrollToCaret(); })); } } // 打開(kāi)連接 Socket socket; private void button1_Click(object sender, EventArgs e) { try { //1創(chuàng)建客戶(hù)端對(duì)象 socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); //bind 如果前后端寫(xiě)的端口一致的時(shí)候 出現(xiàn)錯(cuò)誤,端口號(hào)只能使用一次 //2 綁定ip和端口號(hào) socket.Bind(new IPEndPoint(IPAddress.Parse("192.168.107.83"), 8082)); Thread th = new Thread(f1); th.Start(); } catch (Exception ex) { MessageBox.Show("端口號(hào)被占用"); } } //發(fā)送消息 private void button2_Click(object sender, EventArgs e) { if (socket != null) { //參數(shù)1 發(fā)送的字符串轉(zhuǎn)成字節(jié)數(shù)組 //參數(shù)2 發(fā)送數(shù)據(jù)的遠(yuǎn)程終端 new IPEndPoint(IPAddress.Parse("192.168.107.83"), 8081) socket.SendTo(Encoding.UTF8.GetBytes("倒反天罡"), new IPEndPoint(IPAddress.Parse("192.168.107.83"), 8081)); } } //關(guān)閉 private void button3_Click(object sender, EventArgs e) { socket.Close();//關(guān)閉 socket = null; }
到此這篇關(guān)于C# UDP網(wǎng)絡(luò)通信的實(shí)現(xiàn)示例的文章就介紹到這了,更多相關(guān)C# UDP網(wǎng)絡(luò)通信內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C#使用Lazy實(shí)現(xiàn)延遲加載的方法示例
在C#中,Lazy< T> 類(lèi)是一個(gè)非常有用的工具,它可以用于延遲加載值,在本文中,我們將詳細(xì)介紹 Lazy< T> 的實(shí)現(xiàn)機(jī)制和用法,并提供一些示例來(lái)展示它的優(yōu)勢(shì),文中通過(guò)代碼示例講解的非常詳細(xì),需要的朋友可以參考下2024-06-06C#使用命名管道Pipe進(jìn)行進(jìn)程通信實(shí)例詳解
這篇文章主要介紹了C#使用命名管道Pipe進(jìn)行進(jìn)程通信實(shí)例詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12輕松學(xué)習(xí)C#的基礎(chǔ)入門(mén)
輕松學(xué)習(xí)C#的基礎(chǔ)入門(mén),了解C#最基本的知識(shí)點(diǎn),C#是一種簡(jiǎn)潔的,類(lèi)型安全的一種完全面向?qū)ο蟮拈_(kāi)發(fā)語(yǔ)言,是Microsoft專(zhuān)門(mén)基于.NET Framework平臺(tái)開(kāi)發(fā)的而量身定做的高級(jí)程序設(shè)計(jì)語(yǔ)言,需要的朋友可以參考下2015-11-11C#筆記之EF Code First 數(shù)據(jù)模型 數(shù)據(jù)遷移
EF 中 Code First 的數(shù)據(jù)遷移網(wǎng)上有很多資料,我這份并沒(méi)什么特別。Code First 創(chuàng)建視圖網(wǎng)上也有很多資料,但好像很麻煩,而且親測(cè)好像是無(wú)效的方法(可能是我太笨,沒(méi)搞成功),我摸索出了一種簡(jiǎn)單有效的方法,這里分享給大家2021-09-09C#禁止textbox復(fù)制、粘貼、剪切及鼠標(biāo)右鍵的方法
這篇文章主要介紹了C#禁止textbox復(fù)制、粘貼、剪切及鼠標(biāo)右鍵的方法,涉及C#針對(duì)窗口消息的處理技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-09-09C#實(shí)現(xiàn)獲取系統(tǒng)目錄并以Tree樹(shù)叉顯示的方法
這篇文章主要介紹了C#實(shí)現(xiàn)獲取系統(tǒng)目錄并以Tree樹(shù)叉顯示的方法,可以加深讀者對(duì)于C#下數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn)方法的認(rèn)識(shí),需要的朋友可以參考下2014-07-07C#根據(jù)前臺(tái)傳入實(shí)體名稱(chēng)實(shí)現(xiàn)動(dòng)態(tài)查詢(xún)數(shù)據(jù)
這篇文章主要為大家詳細(xì)介紹了C#如何根據(jù)前臺(tái)傳入實(shí)體名稱(chēng)實(shí)現(xiàn)動(dòng)態(tài)查詢(xún)數(shù)據(jù)的功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下2023-04-04