unity socket异步通信

这是一个使用C#编写的简单TCP服务器和客户端应用程序。服务器端创建了一个连接池来管理客户端连接,当有新的客户端连接时,会将其加入到连接池中,并开始接收数据。接收到数据后,通过`ProcessData`方法解析并打印。客户端则负责连接到服务器并接收服务器发送的数据。整个程序展示了如何使用Socket进行基本的网络通信。
摘要由CSDN通过智能技术生成

using System;
using System.Net.Sockets;
namespace Server
{
    public class Conn
    {
        public const int BUFFER_SIZE = 1024;
        public Socket socket;
        public bool isUse = false;
        public byte[] readBuff = new byte[BUFFER_SIZE];
        public int buffCount = 0;
        public byte[] lenBytes = new byte[sizeof(UInt32)];
        public Int32 msgLength = 0;
        public Conn()
        {
            readBuff = new byte[BUFFER_SIZE];
        }
        // 初始化
        public void Init(Socket socket)
        {
            this.socket = socket;
            isUse = true;
            buffCount = 0;
        }
        public int BuffRemain()
        {
            return BUFFER_SIZE - buffCount;
        }
        public string GetAdress()
        {
            if (!isUse) return " 无法获取地址 ";
            return socket.RemoteEndPoint.ToString();
        }
        public void Close()
        {
            if (!isUse) return;
            socket.Close();
            isUse = false;
            Console.WriteLine(" [ 关闭连接 ] " + GetAdress());
        }

        /*        //发送协议
                public void Send(ProtocolBase protocol)
                {

                }*/
    }
}
 

服务器

using System;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;

namespace Server
{
    public class ServNet
    {
        public Socket listenfd;
        public Conn[] conns;
        public int maxConn = 50;
        //获取连接池索引,返回负数表示获取失败
        public int NewIndex()
        {
            if (conns == null) return -1;
            for(int i = 0; i < conns.Length; i++)
            {
                if (conns[i] == null)
                {
                    conns[i] = new Conn();
                    return i;
                }else if (!conns[i].isUse)
                {
                    return i;
                }
            }
            return -1;
        }
        public void Start(string host,int port)
        {
            conns = new Conn[maxConn];//连接池
            for(int i = 0; i < maxConn; i++)
            {
                conns[i] = new Conn();
            }
            //socket
            listenfd = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            IPAddress ipAdr = IPAddress.Parse(host);
            IPEndPoint ipEp = new IPEndPoint(ipAdr, port);
            listenfd.Bind(ipEp);
            listenfd.Listen(maxConn);
            listenfd.BeginAccept(AcceptCb, null);
            Console.WriteLine("[服务器] 启动成功 ");
        }

        private void AcceptCb(IAsyncResult ar)
        {
            try
            {
                Socket socket = listenfd.EndAccept(ar);
                int index = NewIndex();
                if (index < 0)
                {
                    socket.Close();
                    Console.WriteLine("[ 警告 ] 连接已满 ");
                }
                else
                {
                    Conn conn = conns[index];
                    conn.Init(socket);
                    string adr = conn.GetAdress();
                    Console.WriteLine("客户端 [ " + adr + " ] conn 池 ID:" + index);
                    conn.socket.BeginReceive(conn.readBuff, conn.buffCount, conn.BuffRemain(), SocketFlags.None, ReceiveCb, conn);
                }

            }catch(Exception e)
            {
                Console.WriteLine("AcceptCb 失败:" + e.Message);
            }
            listenfd.BeginAccept(AcceptCb, null);
        }

        private void ReceiveCb(IAsyncResult ar)
        {
            Conn conn = (Conn)ar.AsyncState;
            try
            {
                int count = conn.socket.EndReceive(ar);
                //关闭信号
                if (count <= 0)
                {
                    Console.WriteLine("收到 [ " + conn.GetAdress() + " 客户端断开连接 ");
                    conn.Close();
                    return;
                }

                conn.buffCount += count;
                ProcessData(conn);
                conn.socket.BeginReceive(conn.readBuff, conn.buffCount, conn.BuffRemain(), SocketFlags.None, ReceiveCb, conn);
            }
            catch(Exception e)
            {
                Console.WriteLine("收到 [ " + conn.GetAdress() + " ] 断开连接 {原因: "+e.Message+"}");
                conn.Close();
            }
        }

        private void ProcessData(Conn conn)
        {
            if (conn.buffCount < sizeof(Int32)) { return; }
            Array.Copy(conn.readBuff, conn.lenBytes, sizeof(Int32));
            conn.msgLength = BitConverter.ToInt32(conn.lenBytes, 0);
            if (conn.buffCount < conn.msgLength + sizeof(Int32)) { return; }

            /**************************/
            string str = Encoding.UTF8.GetString(conn.readBuff, sizeof(Int32), conn.msgLength);
            Console.WriteLine(" 收到 [ " + conn.GetAdress() + " ] " + str);
            /**************************/

            int count = conn.buffCount - conn.msgLength - sizeof(Int32);
            Array.Copy(conn.readBuff, sizeof(Int32) + conn.msgLength,conn.readBuff,0,count);
            conn.buffCount = count;
            if (conn.buffCount > 0) ProcessData(conn);
        }

        public void Send(Conn conn, string str)
        {
            byte[] bytes = Encoding.UTF8.GetBytes(str);
            byte[] length = BitConverter.GetBytes(bytes.Length);
            byte[] sendbuff = length.Concat(bytes).ToArray();
            try
            {
                conn.socket.BeginSend(sendbuff, 0, sendbuff.Length, SocketFlags.None, null, null);
            }catch(Exception e)
            {
                Console.WriteLine("[ 发送消息失败 ]" + conn.GetAdress() + "  : {" + e.Message+"}");
            }
        }

        public void Close()
        {
            for(int i = 0; i < conns.Length; i++)
            {
                Conn conn = conns[i];
                if (conn == null) continue;
                if (!conn.isUse) continue;
                lock (conn) { conn.Close(); }
            }
        }
    }
}
 

客户端

using System;
using System.Linq;
using System.Net;
using System.Net.Sockets;

namespace Server
{
    public class ClinNet
    {
        public  Conn listenfd;

        public void Start(string host, int port)
        {
            listenfd = new Conn();
            //socket
            listenfd.Init(new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp));
            IPAddress ipAdr = IPAddress.Parse(host);
            IPEndPoint ipEp = new IPEndPoint(ipAdr, port);
            listenfd.socket.Connect(ipEp);
            listenfd.socket.BeginReceive(listenfd.readBuff, listenfd.buffCount, listenfd.BuffRemain(), SocketFlags.None, ReceiveCb, listenfd);
            Console.WriteLine("[客户端] 启动成功 ");
        }

        private void ReceiveCb(IAsyncResult ar)
        {
            Conn conn = (Conn)ar.AsyncState;
            try
            {
                int count = conn.socket.EndReceive(ar);
                //关闭信号
                if (count <= 0)
                {
                    Console.WriteLine("收到 [ " + conn.GetAdress() + " 服务器已断开连接 ");
                    conn.Close();
                    return;
                }
                conn.buffCount += count;
                ProcessData(conn);
                conn.socket.BeginReceive(conn.readBuff, conn.buffCount, conn.BuffRemain(), SocketFlags.None, ReceiveCb, conn);
            }
            catch (Exception e)
            {
                Console.WriteLine("收到 [ " + conn.GetAdress() + " ] 断开连接 { 错误: " + e.Message + "}");
                conn.Close();
            }
        }
        private void ProcessData(Conn conn)
        {
            if (conn.buffCount < sizeof(Int32)) { return; }
            Array.Copy(conn.readBuff, conn.lenBytes, sizeof(Int32));
            conn.msgLength = BitConverter.ToInt32(conn.lenBytes, 0);
            if (conn.buffCount < conn.msgLength + sizeof(Int32)) { return; }

            /**************************/
            string str = System.Text.Encoding.UTF8.GetString(conn.readBuff, sizeof(Int32), conn.msgLength);
            Console.WriteLine(" 收到 [ " + conn.GetAdress() + " ] " + str);
            /**************************/

            int count = conn.buffCount - conn.msgLength - sizeof(Int32);
            Array.Copy(conn.readBuff, sizeof(Int32) + conn.msgLength, conn.readBuff, 0, count);
            conn.buffCount = count;
            if (conn.buffCount > 0) ProcessData(conn);
        }

        public void Send(string str)
        {
            byte[] bytes = System.Text.Encoding.UTF8.GetBytes(str);
            byte[] length = BitConverter.GetBytes(bytes.Length);
            byte[] sendbuff = length.Concat(bytes).ToArray();
            try
            {
                listenfd.socket.Send(sendbuff);
            }
            catch (Exception e)
            {
                Console.WriteLine("发送消息失败: "+e.Message);
            }
        }
    }
}
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值