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来触发

    简而言之

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

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

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

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

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

  • 相关阅读:
    lsyncd实时同步搭建指南——取代rsync+inotify
    Linux内存管理
    [Python爬虫] 之十一:Selenium +phantomjs抓取活动行中会议活动信息
    [Python爬虫] 之十:Selenium +phantomjs抓取活动行中会议活动
    [Python爬虫] 之九:Selenium +phantomjs抓取活动行中会议活动(单线程抓取)
    python 正则表达式
    Scrapy 安装
    python 安装whl文件
    [Python爬虫] 之八:Selenium +phantomjs抓取微博数据
    [Python爬虫] 之七:selenium webdriver定位不到元素的五种原因及解决办法(转载)
  • 原文地址:https://www.cnblogs.com/ASsss/p/10450562.html
Copyright © 2011-2022 走看看