欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Unity实现局域网聊天室功能

程序员文章站 2022-04-11 23:09:19
基于unity实现一个简单的局域网聊天室,供大家参考,具体内容如下学习unity有一点时间了,之前学的都是做客户端的一些内容,现在开始学习联网。我的这个是在观看了 siki 的教学内容来做的,也有自己...

基于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))
                {
                    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地址和端口号

Unity实现局域网聊天室功能

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

Unity实现局域网聊天室功能

这是服务端的信息

Unity实现局域网聊天室功能

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;

}

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

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

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