Unity实现局域网聊天室功能

编辑: admin 分类: c#语言 发布时间: 2021-11-25 来源:互联网

基于Unity实现一个简单的局域网聊天室,供大家参考,具体内容如下

学习Unity有一点时间了,之前学的都是做客户端的一些内容,现在开始学习联网。我的这个是在观看了 Siki 的教学内容来做的,也有自己的一点点小小的改动在里面。纯粹用于练手了。

因为本人也是小白一枚,所以,有错误的地方或者更好的实现方法,也希望有大神能帮忙指正,多谢!

整体过程分为两部分:构建服务端、构建客户端。

服务端:

大概思路:

1. 声明Socket连接以及绑定IP和端口,这里面使用

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Sockets;
using System.Net;


namespace ServerApplication
{
    class Program
    {
        public static string IP;
        public static int Port;
        static List<Client> clientList = new List<Client>();

        static Socket serverSocket;


        static void Main(string[] args)
        {

            //绑定IP和端口
            BindIPAndPort();
            //
            while (true)
            {
                Socket clientSocket = serverSocket.Accept();
                Client client = new Client(clientSocket);
                clientList.Add(client);
                Console.WriteLine("一台主机进入连接");
            }
        }



        /// <summary>
        /// 广播数据
        /// </summary>
        public static void BroadcostMSG(string s)
        {
            List<Client> NotConnectedList = new List<Client>();
            foreach (var item in clientList)
            {
                if(item.IsConnected)
                {
                    item.SendMSG(s);
                }
                else
                {
                    NotConnectedList.Add(item);
                }

            }

            foreach (var item in NotConnectedList)
            {
                clientList.Remove(item);
            }


        }



        /// <summary>
        /// 绑定IP和端口
        /// </summary>
       public static void BindIPAndPort()
        {

            //创建一个serverSocket
            serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            //声明IP和端口
            Console.WriteLine("输入IP地址:");
            IP = Console.ReadLine();
            string ipStr = IP;


            Console.WriteLine("请输入端口:");
            Port = int.Parse(Console.ReadLine());
            int port = Port;

            IPAddress serverIp = IPAddress.Parse(ipStr);
            EndPoint serverPoint = new IPEndPoint(serverIp, port);

            //socket和ip进行绑定
            serverSocket.Bind(serverPoint);

            //监听最大数为100
            serverSocket.Listen(100);
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Sockets;
using System.Threading;

namespace ServerApplication
{
    class Client
    {
        public Socket clientSocket;
        //声明一个线程用于接收信息
        Thread t;
        //接收信息所用容器
        byte[] data = new byte[1024];

       //构造函数
        public Client(Socket s)
        {
            clientSocket = s;
            t = new Thread(ReceiveMSG);
            t.Start();
        }

        /// <summary>
        /// 接收数据
        /// </summary>
        void ReceiveMSG()
        {
            while(true)
            {
                if (clientSocket.Poll(10,SelectMode.SelectRead))
             【本文由:防cc 提供,感恩】   {
                    break;
                }

                data = new byte[1024];
                int length = clientSocket.Receive(data);
                string message = Encoding.UTF8.GetString(data, 0, length);

                Program.BroadcostMSG(message);
                Console.WriteLine("收到消息:" + message);
            }

        }

        /// <summary>
        /// 发送数据
        /// </summary>
        /// <param name="s"></param>
       public void SendMSG(string message)
        {
            byte[] data = Encoding.UTF8.GetBytes(message);
            clientSocket.Send(data);
        }



        //判断此Client对象是否在连接状态
        public bool IsConnected
        {
            get { return clientSocket.Connected; }
        }

    }
}

客户端:

a.UI界面

UI界面是使用UGUI实现的
登录用户可以自己取名进行登录(发言时用于显示),使用时需要输入服务端的IP地址和端口号

下面是聊天室的页面,在输入框内输入要发送的消息,点击Send,将信息发送出去

这是服务端的信息

b.关于客户端的脚本

(1)这是ClientManager,负责与服务端进行连接,通信

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Net.Sockets;
using System.Net;
using System.Text;
using UnityEngine.UI;
using System.Threading;
public class ClientManager : MonoBehaviour
{
    //ip:192.168.1.7
    public string ipAddressstr;
    public int port;
    public Text ipTextToShow;
    //Socket
    private Socket ClientServer;

    //文本输入框
    public InputField inputTxt;
    public string inputMSGStr;

    //接收
    Thread t;
    public Text receiveTextCom;
    public string message;

    // Use this for initialization
    void Start()
    {
        ipTextToShow.text = ipAddressstr;
       // ConnectedToServer();

    }

    // Update is called once per frame
    void Update()
    {
        if (message != null && message != "")
        {
            receiveTextCom.text = receiveTextCom.text + "\n" + message;
            message = "";
        }
    }


    /// <summary>
    /// 连接服务器
    /// </summary>
    public void ConnectedToServer()
    {
        ClientServer = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

        //声明IP地址和端口
        IPAddress ServerAddress = IPAddress.Parse(ipAddressstr);
        EndPoint ServerPoint = new IPEndPoint(ServerAddress, port);

        ipAddressstr = IpInfo.ipStr;
        port = IpInfo.portStr;


        //开始连接
        ClientServer.Connect(ServerPoint);

        t = new Thread(ReceiveMSG);
        t.Start();

    }


    /// <summary>
    /// 接收消息
    /// </summary>
    /// <returns>“string”</returns>
    void ReceiveMSG()
    {
        while (true)
        {
            if (ClientServer.Connected == false)
            {
                break;
            }
            byte[] data = new byte[1024];
            int length = ClientServer.Receive(data);
            message = Encoding.UTF8.GetString(data, 0, length);
            //Debug.Log("有消息进来");

        }

    }


    /// <summary>
    /// 发送string类型数据
    /// </summary>
    /// <param name="input"></param>
    public void SendMSG()
    {

        Debug.Log("button Clicked");
        //message = "我:" + inputTxt.text;
        inputMSGStr = inputTxt.text;
        byte[] data = Encoding.UTF8.GetBytes(IpInfo.name+":"+inputMSGStr);
        ClientServer.Send(data);

    }

    private void OnDestroy()
    {
        ClientServer.Shutdown(SocketShutdown.Both);
        ClientServer.Close();
    }
    private void OnApplicationQuit()
    {
        OnDestroy();
    }
}

(2)SceneManager,用于场景切换,这里只是利用GameObject进行SetActive()来实现,并不是创建了单独的Scene进行管理。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SceneManager : MonoBehaviour {


    public GameObject loginPanel;
    public GameObject communicatingPanel;
    // Use this for initialization

    public void OnSwitch()
    {
        loginPanel.SetActive(false);
        communicatingPanel.SetActive(true);
    }
}

(3)LogInPanel和IPInfo,一个挂载在登录界面上,一个是数据模型,用于存储数据。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class LogInPanel : MonoBehaviour {


    public Text nameInputTxt;
    public Text ipInputTxt;
    public Text portInputTxt;


    //private string name;
    //private string ipStr;
    //private string portStr;


    public void OnLogInClick()
    {
        IpInfo.name = nameInputTxt.text;
        IpInfo.ipStr = ipInputTxt.text;
        IpInfo.portStr = int.Parse(portInputTxt.text);
    }



}
public static class IpInfo {

    public static string name;
    public static string ipStr;
    public static int portStr;

}

总结:第一次写学习博,还有很多地方要学习啊。

留待解决的问题:此聊天室只能用于局域网以内,广域网就无法实现通信了,还要看看怎么实现远程的一个通信,不然这个就没有存在的意义了。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持海外IDC网。

/r/n【文章出处http://www.1234xp.com/yz.html 欢迎转载】