AhpilyServer.Serverpeer.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace AhpilyServer
{
public class Serverpeer
{
private Socket Socket_服务器;
private Semaphore acceptSemaphore;
/// <summary>
/// 客户端对象的连接池
/// </summary>
private Clientpeerpool client_连接对象池;
#region 开启服务器
/// <summary>
/// 用来开启服务器
/// </summary>
/// <param 端口号="port"></param>
/// <param 最大连接数量="maxCount"></param>
public void Start(int port_端口, int max_最大连接数)
{
try
{
Socket_服务器 = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
acceptSemaphore = new Semaphore(max_最大连接数, max_最大连接数);
//实例化连接池
client_连接对象池 = new Clientpeerpool(max_最大连接数);
//客户端对象=null
Clientpeer Clien_对象 = null;
for (int i = 0; i < max_最大连接数; i++)
{
//客户端对象实例化
Clien_对象 = new Clientpeer();
Clien_对象.ReceiveArgs = new SocketAsyncEventArgs();
Clien_对象.ReceiveArgs.Completed += receive_Completed;
Clien_对象.ReceiveArgs.UserToken = Clien_对象;
//存入连接池
client_连接对象池.Queue_入列(Clien_对象);
Console.WriteLine("对象池实例化:" + i);
}
Console.WriteLine("对象池实例化完成");
//绑定Ip和端口
Socket_服务器.Bind(new IPEndPoint(IPAddress.Any, port_端口));
//设置最大连接数量
Socket_服务器.Listen(max_最大连接数);
Console.WriteLine("服务器启动...");
accept_开始(null);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
#endregion
#region 接受客户端的连接
/// <summary>
/// 开始等待客户端连接
/// </summary>
private void accept_开始(SocketAsyncEventArgs e)
{
if (e == null)
{
e = new SocketAsyncEventArgs();
e.Completed += accpet_异步事件完成;
}
//限制线程的访问
acceptSemaphore.WaitOne();
bool result = Socket_服务器.AcceptAsync(e);
//返回值判断异步事件是否执行完毕 如果返回true 代表真在执行 执行完毕后会触发
// 如果返回false 代表已经执行完毕 直接处理
if (result == false)
{
accept_处理完毕(e);
}
}
/// <summary>
/// 接受连接请求 异步事件完成时触发
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void accpet_异步事件完成(object sender, SocketAsyncEventArgs e)
{
accept_处理完毕(e);
}
/// <summary>
/// 处理连接请求
/// </summary>
private void accept_处理完毕(SocketAsyncEventArgs e)
{
//取出可以断对象
Clientpeer clinet = client_连接对象池.Queue_出列();
clinet.ClientScoket = e.AcceptSocket;
Console.WriteLine("连接处理完毕:" + clinet);
start_接受数据(clinet);
e.AcceptSocket = null;
accept_开始(e);
}
#endregion
#region 接受数据
private void start_接受数据(Clientpeer client)
{
try
{
bool result = client.ClientScoket.ReceiveAsync(client.ReceiveArgs);
if (result == false)
{
pricessReceive(client.ReceiveArgs);
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
/// <summary>
/// 处理接受的请求
/// </summary>
/// <param name="e"></param>
private void pricessReceive(SocketAsyncEventArgs e)
{
Clientpeer clinet = e.UserToken as Clientpeer;
//判断网络消息是否接收成功
if (clinet.ReceiveArgs.SocketError == SocketError.Success && clinet.ReceiveArgs.BytesTransferred > 0)
{
byte[] packet = new byte[clinet.ReceiveArgs.BytesTransferred];
Buffer.BlockCopy(clinet.ReceiveArgs.Buffer, 0, packet, 0, clinet.ReceiveArgs.BytesTransferred);
//让客户端自己处理
clinet.StartReceive(packet);
//
start_接受数据(clinet);
}
//断开连接了
else if(clinet.ReceiveArgs.BytesTransferred == 0)
{
if (clinet.ReceiveArgs.SocketError == SocketError.Success)
{
//客户端主动断开连接
}
else
{
//网络异常断开连接
}
}
}
private void receive_Completed(object sender, SocketAsyncEventArgs e)
{
pricessReceive(e);
}
#endregion
#region 发送数据
#endregion
#region 断开连接
#endregion
}
}
AhpilyServer.Clinetpeer.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace AhpilyServer
{
class Clientpeer
{
public Socket ClientScoket { get; set; }
#region 接受数据
/// <summary>
/// 一旦接受到数据就存到缓存区
/// </summary>
private List<byte> dataCache = new List<byte>();
public SocketAsyncEventArgs ReceiveArgs { get; set; }
private bool IsProcess = false;
public void StartReceive(byte[] packet)
{
dataCache.AddRange(packet);
}
private void processReceive()
{
}
#endregion
}
}
AhpilyServer.Clientpeerpool.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AhpilyServer
{
class Clientpeerpool
{
/// <summary>
/// 客户端连接池
/// </summary>
private Queue<Clientpeer> clientpeerQueue;
public Clientpeerpool(int capacity)
{
clientpeerQueue = new Queue<Clientpeer>(capacity);
}
public void Queue_入列(Clientpeer client)
{
clientpeerQueue.Enqueue(client);
}
public Clientpeer Queue_出列()
{
return clientpeerQueue.Dequeue();
}
}
}
AhpilyServer.EncodeTool.cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AhpilyServer
{
/// <summary>
/// 编码的工具
/// </summary>
public static class EncodeTool
{
public static byte[] EncodeePacket(byte[] data)
{
using (MemoryStream ms = new MemoryStream())
{
using (BinaryWriter bw =new BinaryWriter(ms))
{
bw.Write(data.Length);
bw.Write(data);
byte[] byteArray = new byte[(int)ms.Length];
Buffer.BlockCopy(ms.GetBuffer(),0,byteArray,0,(int)ms.Length);
return byteArray;
}
}
}
/// <summary>
/// 解码的工具
/// </summary>
/// <returns></returns>
public static byte[] DecodePacket(ref List<byte> dataCache)
{
if (dataCache.Count < 4)
throw new Exception("数据缓存长度不足4 不能构成一个完整的消息");
using (MemoryStream ms = new MemoryStream(dataCache.ToArray()))
{
using (BinaryReader br = new BinaryReader(ms))
{
int length = br.ReadInt32();
int dataReaminLength = (int)(ms.Length - ms.Position);
if (length > dataReaminLength)
throw new Exception("数据长度不够包头约定长度 不能构成一个完成的消息");
byte[] data = br.ReadBytes(length);
dataCache.Clear();
dataCache.AddRange(br.ReadBytes(dataReaminLength));
return data;
}
}
}
}
}
GameServer.Program.cs
using AhpilyServer;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GameServer
{
class Program
{
static void Main(string[] args)
{
Serverpeer serverpeer = new Serverpeer();
serverpeer.Start(6666,10);
Console.ReadKey();
}
}
}