using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
namespace RPGServer
{
class NetMgr
{
//Socket对象
Socket socket;
//网络地址
EndPoint endPoint;
//缓冲区
Byte[] recv;
int size = 2048;
/// <summary>
/// 接收消息的委托
/// </summary>
public Action<Player,string> msgHandle;
//构造函数,初始化
public NetMgr(IPAddress ip,int port)
{
endPoint = new IPEndPoint(ip, port);
//recv = new Byte[size];
}
/// <summary>
/// 开启监听
/// </summary>
public void Open()
{
//实例化socket对象
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//绑定地址
socket.Bind(endPoint);
//监听
socket.Listen(0);
//接受客户端异步连接
socket.BeginAccept(new AsyncCallback(AcceptConn), null);
//socket.BeginAccept(AcceptConn, null);
}
/// <summary>
/// 关闭服务
/// </summary>
public void Close()
{
socket.Close();
}
/// <summary>
/// 向所有玩家广播消息
/// </summary>
public void SendToAll(string msg,Player sender)
{
string tempMsg = string.Empty;
foreach (var item in PlayerCache.playDictionary)
{
tempMsg = "3," + sender.UserName + "对大家说:" + msg;
Send(item.Value, tempMsg);
}
}
/// <summary>
/// 向客户端发送消息
/// </summary>
/// <param name="p"></param>
/// <param name="msg"></param>
public void Send(Player p,string msg)
{
if (p.client == null || p.client.Connected == false)
return;
p.client.Send(System.Text.Encoding.UTF8.GetBytes(msg));
}
#region 回调函数
void AcceptConn(IAsyncResult ar)
{
Socket client =socket.EndAccept(ar);
Console.WriteLine("有客户端请求连接" + client.RemoteEndPoint.ToString());
//处理相关逻辑
Player p = new Player();
p.client = client;
PlayerCache.AddPlayer(client.RemoteEndPoint.ToString(), p);
//接受客户端连接
socket.BeginAccept(new AsyncCallback(AcceptConn), null);
//继续异步接收客户端的消息
client.BeginReceive(p.Recv, 0, size, SocketFlags.None, RecCallback, p);
}
#endregion
#region 回调函数
void RecCallback(IAsyncResult ar)
{
Player p = (Player)ar.AsyncState;
//接收到的字节数
int len = p.client.EndReceive(ar);
if (len < 1)
{
p.client.Close();
Console.WriteLine("客户端退出");
return;
}
p.offset = len;
//把字节转换成字符串(解码)
string msg = System.Text.Encoding.UTF8.GetString(p.Recv, 0, len);
if (msgHandle!=null)
{
msgHandle(p,msg);
}
把字节转换成字符串
//string msg = Encoding.UTF8.GetString(recv, 0, len);
//Console.WriteLine(string.Format("客户端{0}说:{1}", p.client.RemoteEndPoint.ToString(), msg));
//接收客户端的消息
p.client.BeginReceive(p.Recv, 0, size, SocketFlags.None, RecCallback, p);
}
#endregion
}
}
玩家缓存类
namespace RPGServer
{
/// <summary>
/// 玩家缓存类
/// </summary>
class PlayerCache
{
/// <summary>
/// 在线玩家
/// </summary>
public static Dictionary<string, Player> playDictionary = new Dictionary<string, Player>();
public static bool AddPlayer(string key, Player p)
{
if (playDictionary.ContainsKey(key))
{
return false;
}
playDictionary.Add(key, p);
return true;
}
public static Player Login(string userName, string pwd)
{
foreach (var item in playDictionary)
{
if (item.Value.UserName==userName&&item.Value.password==pwd)
{
return item.Value;
}
}
return null;
}
}
}
玩家类
class Player
{
public string UserName { get; set; }
public string Name { get; set; }
public string password { get; set; }
public Socket client;
byte[] recv;
public byte[] Recv
{
get { return recv; }
set { recv = value; }
}
public int size;
public int offset;
public bool isLogin;//玩家身份
//构造函数
public Player()
{
size = 2048;
recv = new byte[size];
}
/// <summary>
/// 清除缓冲
/// </summary>
public void ClearBuffer()
{
recv=new byte[size];
}
}
消息处理类
namespace RPGServer
{
class MsgHandle
{
NetMgr net;
public MsgHandle(NetMgr _net)
{
net = _net;
}
public void RecMsgHandleCallback(Player p,string msg)
{
//string msg = System.Text.Encoding.UTF8.GetString(p.Recv, 0, p.offset);
Console.WriteLine(msg);
//实现注册功能
HandleMsg(msg, p);
//p.ClearBuffer();
}
void HandleMsg(string msg, Player p)
{
string[] msgBody = msg.Split(',');
if (msgBody == null || msgBody.Length == 0)
return;
int msgType = int.Parse(msgBody[0]);
Console.WriteLine(msgType);
switch (msgType)
{
case 1://注册
p.UserName = msgBody[1];
p.password = msgBody[2];
p.Name = msgBody[3];
Console.WriteLine("玩家" + p.UserName + "注册成功!");
net.Send(p, "1,0");
break;
case 2://登录
string userName = msgBody[1];
string pwd = msgBody[2];
Player user = PlayerCache.Login(userName, pwd);
if (user!=null)
{//登录成功
user.isLogin = true;
}
string ret = user == null ? "1" : "0";
StringBuilder strBuild = new StringBuilder();
strBuild.Append("2," + ret + "," + userName);
net.Send(p, strBuild.ToString());
break;
case 3:
net.SendToAll(msgBody[1], p);
break;
default:
Console.WriteLine("收到未知命令");
break;
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
namespace RPGServer
{
class Program
{
static string ip = "127.0.0.1";
static int port = 9000;
static void Main(string[] args)
{
bool isQuit = false;
while (!isQuit)
{
NetMgr net = new NetMgr(IPAddress.Any, port);
MsgHandle hand = new MsgHandle(net);
net.Open();
//注册接收消息事件
net.msgHandle += hand.RecMsgHandleCallback;
Console.WriteLine("服务已启动" + ip + ":" + port + "\t" + DateTime.Now.ToString("yyyy/MM/dd hh:mm:ss dddd"));
string cmd = Console.ReadLine();
switch (cmd)
{
case "q":
isQuit = true;
net.Close();
break;
}
break;
}
}
}
}