C#的Socket编程基础——Unity的简单聊天室

经过几个小时的奋斗,终于把这个简单聊天室弄出来了。奋斗奋斗。虽然很简单,但是总归是有收获。

不多说,附上历程:

step 01:首先在vs端搭了一个简单的服务器,结合上一篇的内容做了些改进

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

namespace 聊天室_scoket_tcp服务器
{
    class Program
    {
        static  List<Client> clientlists=new List<Client>();

        /// <summary>
        /// 广播信息
        /// </summary>
        /// <param name="message"></param>
        public static void BroadcastMessage(string message)
        {
            var NotConnectClient = new List<Client>();//掉线线客户端集合
            foreach (var client in clientlists)
            {
                if (client.Connected())//判断是否在线
                {
                    client.SendMessage(message);
                }
                else
                {
                    NotConnectClient.Add(client);
                }
            }
            //将掉线的客户端从集合里移除
            foreach (var temp in NotConnectClient)
            {
                clientlists.Remove(temp);
            }
        }

        static void Main(string[] args)
        {
          Socket tcpServer=new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
          IPAddress ipAddress=IPAddress.Parse("172.25.14.165");
          IPEndPoint ipEndPoint=new IPEndPoint(ipAddress,7799);
          tcpServer.Bind(ipEndPoint);

          Console.WriteLine("服务器开启....");
          tcpServer.Listen(100);
            //循环,每连接一个客户端建立一个Client对象
            while (true)
            {
                Socket clientSocket = tcpServer.Accept();//暂停等待客户端连接,连接后执行后面的代码
                Client client = new Client(clientSocket);//连接后,客户端与服务器的操作封装到Client类中
                Console.WriteLine("一个客户端连接....");
                clientlists.Add(client);//放入集合
            }
        }
    }
}

step 02:新建一个类Client用来服务器端对客户端的数据进行处理接收与广播信息,然后在Program类中的Main()函数的while循环中创建Cilent对象,代码:

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

namespace 聊天室_scoket_tcp服务器
{
    class Client
    {
        private Socket clientSocket;
        private byte[] data=new byte[1024];//存储数据

        public Client(Socket s)
        {
            clientSocket = s;
            //开启一个线程 处理客户端的数据接收
            Thread thread = new Thread(ReceiveMessage);
            thread.Start();
        }

        private void ReceiveMessage()
        {
            //服务器一直接收客户端数据
            while (true)
            {
                //如果客户端掉线,直接出循环
                if (clientSocket.Poll(10,SelectMode.SelectRead))
                {
                    clientSocket.Close();
                    break;
                }
                //接收信息
               int length= clientSocket.Receive(data);
               string message = Encoding.UTF8.GetString(data, 0, length);
                //广播信息
                Program.BroadcastMessage(message);
               Console.WriteLine(message);
            }
        }

        public void SendMessage(string message)
        {
            byte[] data = Encoding.UTF8.GetBytes(message);
            clientSocket.Send(data);
        }

        public bool Connected()
        {
            return clientSocket.Connected;
        }
    }
}

step 03:在unity中搭建一个简单的布局(这个还在最后阻碍了我一下,发信息,显示面板没有内容,Text的这个控件被我弄的太窄了,都么有显示。)


布局中主要有以下几个控件:


step 04:界面搭好后,开始编写Unity客户端的代码,代码逻辑其实并没有什么变化,只是放到unity里运行而已。

using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using UnityEngine;
using System.Collections;
using UnityEngine.UI;

public class ChatClient : MonoBehaviour
{

    public string ipaddress = "172.25.14.165";
    public int  port = 7799;
    private Socket clientSocket;
    public InputField MessageInput;
    public Text MessageText;
    private Thread thread;
    private byte[] data=new byte[1024];// 数据容器
    private string message = "";
	void Start () {
	ConnectToServer();
	}
	
	void Update () {
        //只有在主线程才能更新UI
	  if (message!="" && message!=null)
	   {
	        MessageText.text +="\n"+ message;
	        message = "";
	    }
	}
    /**
     * 连接服务器端函数
     * */
    void ConnectToServer()
    {
        clientSocket=new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
        //跟服务器连接
        clientSocket.Connect(new IPEndPoint(IPAddress.Parse(ipaddress),port));
        //客户端开启线程接收数据
        thread = new Thread(ReceiveMessage);
        thread.Start();

    }

    void ReceiveMessage()
    {
        while (true)
        {
            if (clientSocket.Connected == false)
            {
                break;
            }
        int length=clientSocket.Receive(data);
        message = Encoding.UTF8.GetString(data,0,length);
         print(message);
        }
     
    }

    void SendMessage(string message)
    {
        byte[] data=Encoding.UTF8.GetBytes(message);
        clientSocket.Send(data);
    }

    public void OnSendButtonClick()
    {
        string value = MessageInput.text;
        SendMessage(value);
        MessageInput.text = " ";
    }
    /**
     * unity自带方法
     * 停止运行时会执行
     * */
     void OnDestroy()
    {
        //关闭连接,分接收功能和发送功能,both为两者均关闭
        clientSocket.Shutdown(SocketShutdown.Both);
       clientSocket.Close();
    }
}
好了。以上就整个过程了。并不复杂,只是一直在熟悉Socket的逻辑。

我发布出来一个客户端,unity打开一个客户端,效果显示是可以通信的。

好了。完成了。终于可以睡觉了!!!(遗憾的是最后的运行图没有传上来)。


评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值