Go Zinx与C#实现tcp交互

Go Zinx与C#实现tcp交互

server

服务端是基于Zinx框架开发的服务器应用

func main() {
	//1 创建一个server句柄
	s := znet.NewServer()

	//2 配置路由
	s.AddRouter(0, &PingRouter{})

	//3 开启服务
	s.Serve()
}

Client

客户端使用C#,通过tcp/ip协议和服务端实现数据交互

public class Demo : MonoBehaviour
{
    private TcpClient tcplient;
    private Thread reThread;
    private void Start()
    {
        Connect();
        DelaySendMessage();
    }

    private void Connect()
    {
        int _port = 3653;
        string _ip = "127.0.0.1";

        IPEndPoint RemoteEndPoint = new IPEndPoint(IPAddress.Parse(_ip), _port);
        tcplient = new TcpClient(RemoteEndPoint.AddressFamily);
        tcplient.Connect(RemoteEndPoint);

        Debug.Log("连接成功!");

        //开启新的线程,不停的接收服务器发来的消息
        reThread = new Thread(Received);
        reThread.Start();

    }

    private async void DelaySendMessage()
    {
        await Task.Delay(TimeSpan.FromSeconds(1));
        //向0这个cmd发送hello
        Send(0, "hello");
        DelaySendMessage();
    }

    /// <summary>
    /// 接收服务端返回的消息
    /// </summary>
    void Received()
    {
        while (true)
        {
            NetworkStream networkStream = tcplient.GetStream();
            MUtils.Message message = ByteUtil.UnPack(networkStream);

            Debug.Log("len: " + message.Length);
            Debug.Log("cmd: " + message.Cmd);
            Debug.Log("data: " + Encoding.UTF8.GetString(message.Bytes));
        }
    }

    /// <summary>
    /// 向服务器发送消息
    /// </summary>
    private void Send(int cmd, string str)
    {
        try
        {
            string msg = str;
            byte[] message = Encoding.UTF8.GetBytes(str);
            tcplient.Client.Send(ByteUtil.Pack(cmd, message));
            Debug.Log("send mesg: " + str);
        }
        catch { }
    }
    
}

Client与Server交互

因为Zinx的消息处理采用,[MsgLength]|[MsgID]|[Data]的封包格式,所以客户端向服务器发送数据时,与需要将数据封装成这种格式,接收服务器传来的数据按照格式解包。

public class ByteUtil
    {
        private const int HEAD_BYTES = 4; //包长字节数
        private const int CMD_BYTES = 4;  //CMD字节数

        /// <summary>
        /// 封包
        /// </summary>
        /// <param name="cmd">cmd id</param>
        /// <param name="byteArr">将要发送的byte[]</param>
        /// <returns>返回封装后的byte[]</returns>
        public static byte[] Pack(int cmd, byte[] byteArr)
        {
            int sendLength = byteArr.Length;
            var sendBuffer = new byte[HEAD_BYTES + CMD_BYTES + sendLength];

            // 4个字节的包长
            var headBuffer = BitConverter.GetBytes(sendLength);
            Buffer.BlockCopy(headBuffer, 0, sendBuffer, 0, HEAD_BYTES);

            // 4个字节的CMD
            var cmdBuffer = BitConverter.GetBytes(cmd);
            Buffer.BlockCopy(cmdBuffer, 0, sendBuffer, HEAD_BYTES, CMD_BYTES);

            // 数据体
            Buffer.BlockCopy(byteArr, 0, sendBuffer, HEAD_BYTES + CMD_BYTES, sendLength);

            return sendBuffer;
        }

        /// <summary>
        /// 解包
        /// </summary>
        /// <param name="networkStream"></param>
        public static Message UnPack(NetworkStream networkStream)
        {
            //包长
            byte[] headBuffer = new byte[HEAD_BYTES];
            networkStream.Read(headBuffer, 0, HEAD_BYTES);
            int len = BitConverter.ToInt32(headBuffer, 0);

            // 4个字节的cmd id
            byte[] cmdBuffer = new byte[CMD_BYTES];
            networkStream.Read(cmdBuffer, 0, CMD_BYTES);
            int cmd = BitConverter.ToInt32(cmdBuffer, 0);

            byte[] buffer = new byte[len];
            int total = 0;
            while (total < len)
            {
                total += networkStream.Read(buffer, 0, len);
            }

            Message message = new Message(cmd, len, buffer);
            return message;
        }

        private static void Read(NetworkStream networkStream, byte[] bytes)
        {
            networkStream.Read(bytes, 0, bytes.Length);
        }
    }

    public class Message
    {
        public int Cmd;
        public int Length;
        public byte[] Bytes;

        public Message(int cmd, int dataLen, byte[] bytes)
        {
            this.Cmd = cmd;
            this.Length = dataLen;
            this.Bytes = bytes;
        }
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值