zoukankan      html  css  js  c++  java
  • 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来触发

    简而言之

    第一次,客户端服务端发送断开请求数据包 “我都说完了,今天就到这吧

    ,服务端向客户端发送同意断开数据包恩,好的。

    第三次,服务端再向客户端发送断开请求数据报那我挂了啊?

    第四次客户端再向服务端发送确认断开数据报“拜拜”

    此时服务端断开连接,客户端过会发现服务端没有回复,也断开连接。

  • 相关阅读:
    常用知识点集合
    LeetCode 66 Plus One
    LeetCode 88 Merge Sorted Array
    LeetCode 27 Remove Element
    LeetCode 26 Remove Duplicates from Sorted Array
    LeetCode 448 Find All Numbers Disappeared in an Array
    LeetCode 219 Contains Duplicate II
    LeetCode 118 Pascal's Triangle
    LeetCode 119 Pascal's Triangle II
    LeetCode 1 Two Sum
  • 原文地址:https://www.cnblogs.com/ASsss/p/10450562.html
Copyright © 2011-2022 走看看