您的位置:首页 > 编程语言 > C#

c#异步通讯的例子

2015-07-07 18:38 477 查看
这是一个简单的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<ServerListResp>(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<Server> 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; }

}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: