TCP實現一個簡易的聊天室 (Unity&&C#完成)


  效果展示

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來觸發

簡而言之

第一次,客戶端服務端發送斷開請求數據包 “我都說完了,今天就到這吧

,服務端向客戶端發送同意斷開數據包恩,好的。

第三次,服務端再向客戶端發送斷開請求數據報那我掛了啊?

第四次客戶端再向服務端發送確認斷開數據報“拜拜”

此時服務端斷開連接,客戶端過會發現服務端沒有回復,也斷開連接。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM