这样写服务器和客户端,岂不是很舒服~

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

namespace Server
{
    public class Client
    {
        public Socket socket;
        public string name;
        public byte[] data = new byte[1024];
        public System.IO. MemoryStream my = new MemoryStream();
        public byte[] stream = new byte[0];
        public Timer timer;
        public int id;
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;

namespace Server
{
    class NetManager: Singleton<NetManager>
    {
        Socket server;
        public List<Client> clients = new List<Client>();
        public void Init()
        {
            server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            IPEndPoint ip = new IPEndPoint(IPAddress.Any, 12345);
            server.Bind(ip);
            server.Listen(20);
            Console.WriteLine("服务器开启");
            server.BeginAccept(OnAccept, null);
        }

        private void OnAccept(IAsyncResult ar)
        {
            Socket client = server.EndAccept(ar);
            IPEndPoint iP = client.RemoteEndPoint as IPEndPoint;
            Client cli = new Client();
            cli.socket = client;
            cli.name = iP.Address + ":" + iP.Port;
            clients.Add(cli);
            Console.WriteLine(DateTime.Now.ToString()+ " " + iP.Port + "链接");
            cli.socket.BeginReceive(cli.data, 0, cli.data.Length, SocketFlags.None, OnReceive, cli);
            server.BeginAccept(OnAccept, null);
        }

        private void OnReceive(IAsyncResult ar)
        {
            try
            {
                Client cli = ar.AsyncState as Client;
                int len = cli.socket.EndReceive(ar);
                if (len <= 0)
                {
                    cli.socket.Shutdown(SocketShutdown.Both);
                    cli.socket.Close();
                    clients.Remove(cli);
                    Console.WriteLine(DateTime.Now.ToString() + " " + cli.name + "下线");
                }
                else if (cli.socket.Connected)
                {
                    byte[] data = new byte[len];
                    Buffer.BlockCopy(cli.data, 0, data, 0, data.Length);
                    //创建一个临时流
                    byte[] liu = new byte[cli.stream.Length + data.Length];
                    Buffer.BlockCopy(cli.stream, 0, liu, 0, cli.stream.Length);
                    Buffer.BlockCopy(data, 0, liu, cli.stream.Length, data.Length);
                    //把流替换为临时流
                    cli.stream = liu;
                    //流长度大于等于2说明流内有数据
                    while (cli.stream.Length >= 2)
                    {
                        //获取一个包的长度
                        ushort onelen = BitConverter.ToUInt16(cli.stream, 0);
                        //如果流的长度大于等于包的长度+2说明有一个完整包
                        if (cli.stream.Length >= 2 + onelen)
                        {
                            //获取一个完整包
                            byte[] onedata = new byte[onelen];
                            Buffer.BlockCopy(cli.stream, 2, onedata, 0, onedata.Length);
                            //获取包的消息号
                            int id = BitConverter.ToInt32(onedata, 0);
                            //获取包的消息体
                            byte[] body = new byte[onedata.Length - 4];
                            Buffer.BlockCopy(onedata, 4, body, 0, body.Length);
                            //消息分发
                            Console.WriteLine("收到消息:id" + id);
                            MessageCenter.Ins.Send(id, body, cli);
                            //剩余长度
                            int sylen = cli.stream.Length - (2 + onelen);
                            //剩余长度大于0说明还有包
                            if (sylen > 0)
                            {
                                byte[] sydata = new byte[sylen];
                                Buffer.BlockCopy(cli.stream, 2 + onelen, sydata, 0, sylen);
                                cli.stream = sydata;
                            }
                            else
                            {
                                cli.stream = new byte[0];
                            }
                        }
                        else
                        {
                            break;
                        }
                    }

                    cli.socket.BeginReceive(cli.data, 0, cli.data.Length, SocketFlags.None, OnReceive, cli);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                throw;
            }
        }
        public void Send(int id, byte[] body, Client cli)
        {
            byte[] head = BitConverter.GetBytes(id);
            byte[] data = new byte[head.Length + body.Length];
            Buffer.BlockCopy(head, 0, data, 0, head.Length);
            Buffer.BlockCopy(body, 0, data, head.Length, body.Length);
            //手动拼接长度
            byte[] mylen = BitConverter.GetBytes((ushort)data.Length);
            byte[] myData = new byte[mylen.Length + data.Length];
            Buffer.BlockCopy(mylen, 0, myData, 0, mylen.Length);
            Buffer.BlockCopy(data, 0, myData, mylen.Length, data.Length);
            cli.socket.BeginSend(myData, 0, myData.Length, SocketFlags.None, OnSend, cli);
        }

        private void OnSend(IAsyncResult ar)
        {
            Client cli = ar.AsyncState as Client;
            int len = cli.socket.EndSend(ar);
            
    }
}

以上是服务器的代码

----------------------------------------------------------------------------------------------------------------------------

下面是客户端的代码

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using UnityEngine;

public class NetClient : Singleton<NetClient>
{
    public Socket m_Sockets;//客户端的通讯类
    public Queue<byte[]> m_que = new Queue<byte[]>();//客户端队列用于保存流数据ID和包
    public byte[] m_Data = new byte[1024];//缓存
    public byte[] m_Stream = new byte[0];//流
    public void Init()
    {
        m_Sockets = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//创建通讯类
        m_Sockets.BeginConnect("127.0.0.1", 12345, OnConnect, null);//给服务器发消息127.0.0.1是本机ID 3000是服务器端口
    }

    private void OnConnect(IAsyncResult ar)
    {
        m_Sockets.EndConnect(ar);//
        m_Sockets.BeginReceive(m_Data, 0, m_Data.Length, SocketFlags.None, OnReceive, null);//接收服务器发送的数据

    }

    private void OnReceive(IAsyncResult ar)
    {
        int len = m_Sockets.EndReceive(ar);//接收的长度
        if (len > 0)
        {
            byte[] data = new byte[len];
            Buffer.BlockCopy(m_Data, 0, data, 0, len);
            m_Stream = m_Stream.Concat(data).ToArray();
            while (m_Stream.Length > 2)
            {
                ushort bodyLen = BitConverter.ToUInt16(m_Stream, 0);
                int allLen = bodyLen + 2;
                if (m_Stream.Length >= allLen)
                {
                    byte[] oneData = new byte[bodyLen];
                    Buffer.BlockCopy(m_Stream, 2, oneData, 0, bodyLen);
                    m_que.Enqueue(oneData);
                    int syLen = m_Stream.Length - allLen;
                    if (syLen > 0)
                    {
                        byte[] syBody = new byte[syLen];
                        Buffer.BlockCopy(m_Stream, allLen, syBody, 0, syLen);
                        m_Stream = syBody;
                    }
                    else
                    {
                        m_Stream = new byte[0];
                        break;
                    }
                }
                else
                {
                    break;
                }
            }
            m_Sockets.BeginReceive(m_Data, 0, m_Data.Length, SocketFlags.None, OnReceive, null);
        }
    }

    public void Send(int id, byte[] body)
    {
        byte[] head = BitConverter.GetBytes(id);
        byte[] len = BitConverter.GetBytes((ushort)(head.Length + body.Length));
        byte[] data = new byte[0];
        data = data.Concat(len).ToArray();
        data = data.Concat(head).ToArray();
        data = data.Concat(body).ToArray();
        m_Sockets.BeginSend(data, 0, data.Length, SocketFlags.None, OnSend, null);
    }
    private void OnSend(IAsyncResult ar)
    {
        int len = m_Sockets.EndSend(ar);
        Debug.Log("客户端发送长度:" + len);
    }
    public void Updata()
    {
        if (m_que.Count > 0)
        {
            byte[] oneData = m_que.Dequeue();
            int id = BitConverter.ToInt32(oneData, 0);
            byte[] body = new byte[oneData.Length - 4];
            Buffer.BlockCopy(oneData, 4, body, 0, body.Length);
            MessageCenter.Ins.BoardMes(id, body);
        }
    }

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值