效果展示 TCP Transmission Control Protocol 傳輸控制協議 TCP是面向連接的流模式(俗稱:網路流)。即傳輸數據之前源端和終端建立可靠的連接,保證數據傳輸的正確性。 流模式:由於建立連接,收到的數據都是同一主機發送的,所有可以發送端Write一次,接收端Read多次; ...
效果展示
TCP
Transmission Control Protocol 傳輸控制協議
TCP是面向連接的流模式(俗稱:網路流)。即傳輸數據之前源端和終端建立可靠的連接,保證數據傳輸的正確性。
流模式:由於建立連接,收到的數據都是同一主機發送的,所有可以發送端Write一次,接收端Read多次;也可以發送端Write多次,接收端Read多次。但每次傳輸數據最大為1460位元組。
實現步驟
服務端 客戶端
獲取本機終結點 獲取伺服器終結點
創建TcpListener對象,開啟偵聽器 創建TcpClient對象
等待客戶端連接 連接伺服器
獲取針對客戶端連接的網路流客戶端通信 通過網路流與伺服器通信
…… ……
關閉連接 關閉連接
using System.Collections; using System.Collections.Generic; using System.Net.Sockets; using UnityEngine; using Common; using UnityEngine.UI; using System.Net; using System; using System.Text; /// <summary> /// TCP 客戶端 發送消息 /// </summary> public class ChatTCPClientTest : MonoBehaviour { private InputField messageInput; private TcpClient tcpClient; private void Start() { var server = FindObjectOfType<ChatTCPServerTest>(); IPEndPoint ep = new IPEndPoint(IPAddress.Parse(server.serverIP), server.serverPort); //創建終結點 tcpClient = new TcpClient(); //1. 創建Socket tcpClient.Connect(ep); ////三次握手(連接請求) //使用指定的遠程網路終結點將客戶端連接到TCP主機 messageInput = transform.FindChildByName("MessageInput").GetComponent<InputField>(); transform.FindChildByName("Send").GetComponent<Button>().onClick.AddListener(OnSendButtonClient); } private void OnSendButtonClient() { SendChatMessage(messageInput.text); } private void SendChatMessage(string msg) { //獲取網路流 NetworkStream stream = tcpClient.GetStream(); //用於發送消息和接收消息 byte[] dgramContent = Encoding.UTF8.GetBytes(msg); //傳入內容 stream.Write(dgramContent, 0, dgramContent.Length); //寫入網路流 內容 從那開始發 發的長度 } /// <summary> /// 3.關閉連接/釋放資源 /// </summary> private void OnApplicationQuit() { tcpClient.Close(); } }ChatTCPClientTest
using System.Collections; using System.Collections.Generic; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; using UIWidgetsSamples; using UnityEngine; using Common; using System; /// <summary> /// 服務端 TCP 接收消息 /// </summary> public class ChatTCPServerTest : MonoBehaviour { public string serverIP; //IP public int serverPort; //埠 //1.創建Socket對象 private ChatView chatView; private void Start() { chatView = transform.FindChildByName("ChatView").GetComponent<ChatView>(); IPEndPoint ep = new IPEndPoint(IPAddress.Parse(serverIP), serverPort); //1). 創建對象並開啟監聽 serverlisten = new TcpListener(ep);//需要一個終結點 serverlisten.Start(); //2.線程 thread = new Thread(ReceiveClient); thread.Start(); } private TcpListener serverlisten; private Thread thread; //2.開啟監聽 //3.接收數據 顯示 private void ReceiveClient() { TcpClient client = serverlisten.AcceptTcpClient(); //接收消息 //AcceptTcpClient() 接受掛起連接請求 NetworkStream stream = client.GetStream(); //讀取網路流到容器 byte[] date = new byte[1024]; //返回讀了多少位元組 //Read讀取消息 如果沒有讀取到 線程阻塞 //如果有多個客戶端 要迴圈接收 將讀到的信息放到線程中 int count; while((count=stream.Read(date,0,date.Length))>0) //count為0 表示客戶端下線 { //解析 string msg = Encoding.UTF8.GetString(date); ThreadCrossHelper.Instance.ExecuteOnMainThread(() => { ShowMessage(msg); }); } client.Close();//關閉Socket對象 自動釋放流 } private void ShowMessage(string msg) { chatView.DataSource.Add(new ChatLine() { UserName = "AnnS", Message = msg, Time = DateTime.Now, Type = ChatLineType.User, }); } //4.關閉 public void OnApplicationQuit() { thread.Abort(); serverlisten.Stop(); } }ChatTCPServerTest
中間發生連接請求過程(三次握手) , 斷開連接(四次揮手)
三次握手
所謂三次握手就是建立TCP連接的過程,需要客戶端和服務端總共發送3個包確認連接成功。在socket編程中,這一過程由客戶端執行connect來觸發。
簡而言之:
第一次,客戶端向服務端發出連接請求數據包。 “我想跟你聊會,可以嗎?”
第二次,服務端向客戶端發送同意連接和要求同步的數據包。“可以,什麼時候啊?”
第三次,客戶端再發出一個數據包確認伺服器的同步要求。“就現在。”
四次揮手
所謂四次揮手就是終止TCP連接的過程,需要客戶端和服務端總共發送4個包以確認連接斷開。在socket編程中,這一過程由客戶端或服務端任一方執行close來觸發
簡而言之:
第一次,客戶端向服務端發送斷開請求數據包。 “我都說完了,今天就到這吧”
第二次,服務端向客戶端發送同意斷開數據包。“恩,好的。”
第三次,服務端再向客戶端發送斷開請求數據報。“那我掛了啊?”
第四次,客戶端再向服務端發送確認斷開數據報。“拜拜”
此時服務端斷開連接,客戶端過會發現服務端沒有回覆,也斷開連接。