这是一个简单的c#异步通讯的例子(只有客户端哦)

  • C# 异步通讯

  • 自定义数据头

  • protobuf

  • 数据缓冲,解包

代码伺候:

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Net;using System.Net.Sockets;using System.IO;using System.Threading;using ProtoBuf;namespace ProtobufExample{    class Program    {        static byte[] buffer = new byte[1024];        static int writeIndex = 0;        static int readIndex = 0;        private static Packet current;        private static TcpClient client;        private static NetworkStream networkStream;        static void Main(string[] args)        {            IPAddress address=new IPAddress(new byte[]{127,0,0,1});            Int32 port=8000;            client = new TcpClient();            client.BeginConnect(address,port,new AsyncCallback(ConnectCallback),client);            while (true)            {                if (networkStream != null)                {                    write(client);                }                Thread.Sleep(100);            }        }        public static void ConnectCallback(IAsyncResult result) {            TcpClient client=(TcpClient)result.AsyncState;            client.EndConnect(result);            networkStream = client.GetStream();            read(client);        }        private static void write(TcpClient client)        {            //发送请求游戏服列表协议            Packet packet = new Packet();            packet.Header.Pid = 10001;            byte[] data=new byte[PacketHeader.header_size];            packet.Header.serialize(data,0);            networkStream.BeginWrite(data, 0, data.Length, new AsyncCallback(WriteCallback), networkStream);        }        public static void WriteCallback(IAsyncResult result) {            NetworkStream networkStream = (NetworkStream)result.AsyncState;            networkStream.EndWrite(result);            Console.WriteLine("数据包已发送");        }        public static void read(TcpClient client) {             NetworkStream networkStream=client.GetStream();            networkStream.BeginRead(buffer, writeIndex, buffer.Length - writeIndex, new AsyncCallback(ReadCallback), networkStream);        }        public static void ReadCallback(IAsyncResult result) {            NetworkStream networkStream = (NetworkStream)result.AsyncState;            int readbytes=networkStream.EndRead(result);            writeIndex += readbytes;            Console.WriteLine("读取字节数:"+readbytes);            Packet packet = null;            while ((packet = readPacket())!=null) {                Console.WriteLine("收到协议:" + packet.Header.Pid);                MemoryStream ms = new MemoryStream(packet.Content);                ServerListResp resp=Serializer.Deserialize
(ms);                Console.WriteLine("服务器列表:" + resp.servers.Count);            }            networkStream.BeginRead(buffer, writeIndex, buffer.Length - writeIndex, new AsyncCallback(ReadCallback), networkStream);        }        public static Packet readPacket()         {            if (PacketHeader.header_size > writeIndex - readIndex)            {                return null;            }            if (current == null)            {                current = new Packet();            }            Packet temp = current;            temp.Header.deserialize(buffer, readIndex);            readIndex += PacketHeader.header_size;            if (temp.Header.BodyLength > writeIndex - readIndex)            {                return null;            }            byte[] data = new byte[temp.Header.BodyLength];            Array.Copy(buffer,readIndex,data,0,temp.Header.BodyLength);            temp.Content = data;                     readIndex += temp.Header.BodyLength;            discardReadBytes();            return temp;        }        private static void discardReadBytes() {            if (readIndex == writeIndex) {                writeIndex =0;                readIndex = writeIndex;            }            else            {                int remaining = writeIndex - readIndex;                byte[] temp = new byte[remaining];                Array.Copy(buffer, readIndex, temp, 0, remaining);                writeIndex = remaining;                readIndex = 0;                Array.Copy(temp,buffer, remaining);            }        }    }}using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace ProtobufExample{    class PacketHeader    {        public static  int header_size = 6;        private int pid;        private int code;        private int bodyLength;        public void deserialize(byte[] src,int offset) {            this.code = src[offset] <<8|src[offset+1];            this.pid = src[offset+2] << 8 | src[offset + 3];            this.bodyLength = src[offset+4] << 8 | src[offset + 5];     }     public void serialize(byte[] dist,int offset) {            dist[offset]=(byte)(this.code>>8&0xff);            dist[offset+1] = (byte)(this.code & 0xff);            dist[offset + 2] = (byte)(this.pid >> 8 & 0xff);            dist[offset + 3] = (byte)(this.pid & 0xff);            dist[offset + 4] = (byte)(this.bodyLength >> 8 & 0xff);            dist[offset + 5] = (byte)(this.bodyLength & 0xff);     }        public int BodyLength        {            get{return bodyLength;}            set{this.bodyLength=value;}        }        public int Pid        {            get { return pid; }            set { this.pid = value; }        }    }    class Packet    {        private PacketHeader header;        private byte[] content;        public PacketHeader Header         {            get            {                if(header==null)                {                    header=new PacketHeader();                }                return header;            }            set            {               this.header=value;            }        }        public byte[] Content        {            get            {                return content;            }            set            {                this.content = value;            }        }    }}
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using ProtoBuf;namespace ProtobufExample{    [ProtoContract]    class ServerListResp    {        [ProtoMember(1)]        public List
 servers { get; set; }    }    [ProtoContract]    class Server    {        [ProtoMember(1)]        public Int32 serverId {get;set;}        [ProtoMember(2)]        public string serverName { get; set; }        [ProtoMember(3)]        public Int32 serverStatus { get; set; }        [ProtoMember(4)]        public Int32 serverLabel { get; set; }    }}