Soket服务器-客户端交互

using System;
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;
            }
        }
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值