TCP(Transmission Control Protocol
傳輸控制協議)是一種面向連接的、可靠的、基於字節流的傳輸層通信協議,由IETF的RFC 793定義。在簡化的計算機網絡OSI模型中,它完成第四層傳輸層所指定的功能,用戶數據報協議(UDP)是同一層內[1] 另一個重要的傳輸協議。在因特網協議族(Internet protocol suite)中,TCP層是位於IP層之上,應用層之下的中間層。不同主機的應用層之間經常需要可靠的、像管道一樣的連接,但是IP層不提供這樣的流機制,而是提供不可靠的包交換。[1]
應用層向TCP層發送用於網間傳輸的、用8位字節表示的數據流,然后TCP把數據流分區成適當長度的報文段(通常受該計算機連接的網絡的數據鏈路層的最大傳輸單元(
[1]
MTU)的限制)。之后TCP把結果包傳給IP層,由它來通過網絡將包傳送給接收端實體
[1] 的TCP層。TCP為了保證不發生丟包,就給每個包一個序號,同時序號也保證了傳送到接收端實體的包的按序接收。然后接收端實體對已成功收到的包發回一個相應的確認(ACK);如果發送端實體在合理的往返時延(RTT)內未收到確認,那么對應的數據包就被假設為已丟失將會被進行重傳。TCP用一個校驗和函數來檢驗數據是否有錯誤;在發送和接收時都要計算校驗和。
[1]
UDP 是User Datagram Protocol的簡稱, 中文名是用戶數據報協議,是OSI(Open System Interconnection,開放式系統互聯) 參考模型中一種無連接的
傳輸層協議,提供面向事務的簡單不可靠信息傳送服務,IETF RFC 768是UDP的正式規范。UDP在IP報文的協議號是17。
UDP協議全稱是用戶數據報協議
[1] ,在
網絡中它與
TCP協議一樣用於處理數據包,是一種無連接的協議。在
OSI模型中,在第四層——
傳輸層,處於IP協議的上一層。UDP有不提供數據包分組、組裝和不能對數據包進行排序的缺點,也就是說,當報文發送之后,是無法得知其是否安全完整到達的。UDP用來支持那些需要在
計算機之間傳輸數據的網絡應用。包括網絡視頻會議系統在內的眾多的客戶/服務器模式的網絡應用都需要使用UDP協議。UDP協議從問世至今已經被使用了很多年,雖然其最初的光彩已經被一些類似協議所掩蓋,但是即使是在今天UDP仍然不失為一項非常實用和可行的網絡傳輸層協議。
與所熟知的TCP(
傳輸控制協議)協議一樣,UDP協議直接位於IP(網際協議)協議的頂層。根據OSI(
開放系統互連)參考模型,UDP和TCP都屬於傳輸層協議。UDP協議的主要作用是將
網絡數據流量壓縮成數據包的形式。一個典型的數據包就是一個二進制數據的傳輸單位。每一個數據包的前8個字節用來包含報頭信息,剩余字節則用來包含具體的傳輸數據。
TCP與UDP區別
TCP---傳輸控制協議,提供的是面向連接、可靠的字節流服務。當客戶和服務器彼此交換數據前,必須先在雙方之間建立一個TCP連接,之后才能傳輸數據。TCP提供超時重發,丟棄重復數據,檢驗數據,流量控制等功能,保證數據能從一端傳到另一端。 UDP---用戶數據報協議,是一個簡單的面向數據報的運輸層協議。UDP不提供可靠性,它只是把應用程序傳給IP層的數據報發送出去,但是並不能保證它們能到達目的地。由於UDP在傳輸數據報前不用在客戶和服務器之間建立一個連接,且沒有超時重發等機制,故而傳輸速度很快
有人說TCP就像打電話,必須接通后才能通信,而UDP就像發短信一樣,不需要接通就可以發送。比喻甚是恰當啊。
內容大部分來源於網絡,不喜勿噴啊!
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; namespace SocketClient { public partial class Form1 : Form { public Form1() { InitializeComponent(); CheckForIllegalCrossThreadCalls = false; } private void button1_Click(object sender, EventArgs e) { IPEndPoint serverIP = new IPEndPoint(IPAddress.Parse(textBox1.Text), Convert.ToInt32(textBox2.Text)); if (comboBox1.SelectedItem.ToString() == "TCP") { TcpServer(serverIP); } else if (comboBox1.SelectedItem.ToString() == "UDP") { UdpClient(serverIP); } } #region TCP連接方式 /// <summary> /// TCP連接方式 /// </summary> /// <param name="serverIP"></param> Socket tcpClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); public void TcpServer(IPEndPoint serverIP) { listBox1.Items.Add("客戶端啟動TCP連接模式"); try { tcpClient.Connect(serverIP);//連接 button1.Enabled = false; button1.BackColor = Color.Red; textBox1.Enabled = false; comboBox1.Enabled = false; textBox2.Enabled = false; } catch (SocketException e) { listBox1.Items.Add(string.Format("連接出錯:{0}", e.Message)); return; } listBox1.Items.Add("客戶端:client-->server"); new Thread(() => { while (true) { byte[] data = new byte[1024]; try { int length = tcpClient.Receive(data); } catch (Exception ex) { //listBox1.Items.Add("出現異常"); break; } listBox1.Items.Add(string.Format("{0} 收到消息:{1}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), Encoding.UTF8.GetString(data))); } }).Start(); } #endregion #region UDP連接方式 /// <summary> /// UDP連接方式 /// </summary> /// <param name="serverIP"></param> Socket udpClient = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); public void UdpClient(IPEndPoint serverIP) { listBox1.Items.Add("客戶端啟動UDP模式"); udpClient.SendTo(Encoding.UTF8.GetBytes(textBox3.Text), SocketFlags.None, serverIP); IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0); EndPoint Remote = (EndPoint)sender; button1.Enabled = false; button1.BackColor = Color.Red; textBox1.Enabled = false; comboBox1.Enabled = false; textBox2.Enabled = false; new Thread(() => { while (true) { byte[] data = new byte[1024]; try { int length = udpClient.ReceiveFrom(data, ref Remote);//接受來自服務器的數據 } catch (Exception ex) { // listBox1.Items.Add(string.Format("出現異常:{0}", ex.Message)); break; } listBox1.Items.Add(string.Format("{0} 收到消息:{1}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), Encoding.UTF8.GetString(data))); } }).Start(); } #endregion private void button2_Click(object sender, EventArgs e) { if (comboBox1.SelectedItem.ToString()=="TCP") { tcpClient.Send(Encoding.UTF8.GetBytes(textBox3.Text)); listBox1.Items.Add(string.Format("{0}發送消息:{1}",DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), textBox3.Text)); } else if(comboBox1.SelectedItem.ToString()=="UDP") { listBox1.Items.Add(string.Format("{0}發送消息:{1}",DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), textBox3.Text)); } } private void button3_Click(object sender, EventArgs e) { tcpClient.Close(); udpClient.Close(); Application.Exit(); } } }
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; namespace SocketClient { public partial class Form1 : Form { public Form1() { InitializeComponent(); CheckForIllegalCrossThreadCalls = false; } private void button1_Click(object sender, EventArgs e) { IPEndPoint serverIP = new IPEndPoint(IPAddress.Parse(textBox1.Text), Convert.ToInt32(textBox2.Text)); if (comboBox1.SelectedItem.ToString() == "TCP") { TcpServer(serverIP); } else if (comboBox1.SelectedItem.ToString() == "UDP") { UdpClient(serverIP); } } #region TCP連接方式 /// <summary> /// TCP連接方式 /// </summary> /// <param name="serverIP"></param> Socket tcpClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); public void TcpServer(IPEndPoint serverIP) { listBox1.Items.Add("客戶端啟動TCP連接模式"); try { tcpClient.Connect(serverIP);//連接 button1.Enabled = false; button1.BackColor = Color.Red; textBox1.Enabled = false; comboBox1.Enabled = false; textBox2.Enabled = false; } catch (SocketException e) { listBox1.Items.Add(string.Format("連接出錯:{0}", e.Message)); return; } listBox1.Items.Add("客戶端:client-->server"); new Thread(() => { while (true) { byte[] data = new byte[1024]; try { int length = tcpClient.Receive(data); } catch (Exception ex) { //listBox1.Items.Add("出現異常"); break; } listBox1.Items.Add(string.Format("{0} 收到消息:{1}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), Encoding.UTF8.GetString(data))); } }).Start(); } #endregion #region UDP連接方式 /// <summary> /// UDP連接方式 /// </summary> /// <param name="serverIP"></param> Socket udpClient = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); public void UdpClient(IPEndPoint serverIP) { listBox1.Items.Add("客戶端啟動UDP模式"); udpClient.SendTo(Encoding.UTF8.GetBytes(textBox3.Text), SocketFlags.None, serverIP); IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0); EndPoint Remote = (EndPoint)sender; button1.Enabled = false; button1.BackColor = Color.Red; textBox1.Enabled = false; comboBox1.Enabled = false; textBox2.Enabled = false; new Thread(() => { while (true) { byte[] data = new byte[1024]; try { int length = udpClient.ReceiveFrom(data, ref Remote);//接受來自服務器的數據 } catch (Exception ex) { // listBox1.Items.Add(string.Format("出現異常:{0}", ex.Message)); break; } listBox1.Items.Add(string.Format("{0} 收到消息:{1}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), Encoding.UTF8.GetString(data))); } }).Start(); } #endregion private void button2_Click(object sender, EventArgs e) { if (comboBox1.SelectedItem.ToString()=="TCP") { tcpClient.Send(Encoding.UTF8.GetBytes(textBox3.Text)); listBox1.Items.Add(string.Format("{0}發送消息:{1}",DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), textBox3.Text)); } else if(comboBox1.SelectedItem.ToString()=="UDP") { listBox1.Items.Add(string.Format("{0}發送消息:{1}",DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), textBox3.Text)); } } private void button3_Click(object sender, EventArgs e) { tcpClient.Close(); udpClient.Close(); Application.Exit(); } } }
感謝園友
http://www.cnblogs.com/hongfei/archive/2012/12/08/2808771.html
http://www.cnblogs.com/zengqinglei/archive/2013/04/27/3046119.html
http://zhidao.baidu.com/link?url=HNMpttFbHTevgWwye0rPGiGuQGihHOaNNKbpJZ7CvEn8YjWr2w_5Ok_YUx1xd73yxTt9k6STVaMMuzuGINqQKK