首页 > 其他 > 详细

Xamarin Studio 与Socket架设简易服务器

时间:2021-03-07 15:23:49      阅读:22      评论:0      收藏:0      [点我收藏+]

一、Xamarin Studio

技术分享图片

 

 用于架设服务器的关键平台.

二、文件结构

技术分享图片

 

 三、代码

Program.cs

using System;
using System.Net;
using System.Net.Sockets;
using System.Collections.Generic;
using System.Reflection;
using System.Linq;

public class ClientState{
    public Socket socket;
    //接收缓冲区
    public byte[] readBuff = new byte[1024];
    //接收缓冲区的数据长度
    public int buffCount = 0;

    public int hp = -100;
    public float x = 0;
    public float y = 0;
    public float z = 0;
    public float eulY = 0;

}
class MainClass
{
    //int buffCount = 0;
    //监听Socket
    static Socket listenfd;
    //客户端Socket及状态信息-----clients
    public static Dictionary<Socket,ClientState> clients =new Dictionary<Socket,ClientState>();
    public static void Main(string[] args)
  {
    //Socket-----listenfd------监听端或称服务端
        listenfd = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);

        //局域网IP处理
        string hostName = Dns.GetHostName();                    //获取主机名称  
        Console.WriteLine("主机:" + hostName);
        IPAddress[] addresses = Dns.GetHostEntry(Dns.GetHostName()).AddressList; //解析主机IP地址
        Console.WriteLine("IP:" + addresses[1]);

    //Bind-------绑定服务端IP及端口
        IPAddress ipAdr = IPAddress.Parse(addresses[1].ToString());
        IPEndPoint ipEp = new IPEndPoint(ipAdr,8888);
        listenfd.Bind(ipEp);

    //Listen-------启动服务器并开启监听
        listenfd.Listen(0);
        Console.WriteLine("[服务器]启动成功,并已开启监听!");

    //checkRead-----------socket终端列表
        List<Socket> checkRead = new List<Socket>();
        Console.WriteLine("建立checkRead-----------socket终端列表");
        //主循环-----等待触发
        Console.WriteLine("开启主循环(不间断)-----等待触发");
        while(true)
        {
      //填充checkRead列表

            checkRead.Clear();
            checkRead.Add(listenfd); //添加监听终端socket

            foreach(ClientState s in clients.Values)
            {
                checkRead.Add(s.socket);//添加客户端socket

      }
           //select---------多路复用,就是同时处理多路信号,比如同时检测多个Socket的状态。
            Socket.Select(checkRead,null,null,1000);

      //检查可读对象
            foreach(Socket s in checkRead)
            {
                if(s == listenfd)
                {
                    ReadListenfd(s);
         }
         else{
                    ReadClientfd(s);
         }
      }
    }
  }
    //读取Listenfd------监听端信息
    public static void ReadListenfd(Socket listenfd)
    {
        
        Console.WriteLine("读取Listenfd------监听端信息-------开启Accept");
        Socket clientfd = listenfd.Accept();
        ClientState state = new ClientState();
        state.socket = clientfd;
        clients.Add(clientfd,state);
}
    //读取Clientfd------客户端信息
    public static bool ReadClientfd(Socket clientfd)
    {
        Console.WriteLine("读取Clientfd------客户端信息");
        ClientState state = clients[clientfd];
      //接收
        int count = 0;
        //byte[] bufferTmp = new byte[1024];

      try
        {
            count = clientfd.Receive(state.readBuff);
        }
        catch(SocketException ex)
        {
            MethodInfo mei = typeof(EventHandler).GetMethod("OnDisconnect");
            object[] ob = { state };
            mei.Invoke(null,ob);

            clientfd.Close();
            clients.Remove(clientfd);
            Console.WriteLine("Receive SocketException " + ex.ToString());
        return false;
      }
        //客户端关闭
        if(count == 0)
        {
            MethodInfo mei = typeof(EventHandler).GetMethod("OnDisconnect");
            object[] ob = { state };
            mei.Invoke(null,ob);

            clientfd.Close();
            clients.Remove(clientfd);
            Console.WriteLine("Socket Close");
        return false;
      }
        //消息处理
        MethodInfo mei1 = typeof(MainClass).GetMethod("DealWithMsg");
        object[] ob1 = { state,count };
        mei1.Invoke(null, ob1);

        return true;
    }
    public static void Send(ClientState c, string sendStr)
    {
        byte[] sendBytes = System.Text.Encoding.Default.GetBytes(sendStr);
        c.socket.Send(sendBytes);
    }
    public static void DealWithMsg(ClientState state,int buffCount)
    {
        Console.WriteLine("DealWithMsg!");
        if (buffCount <= 2)
            return;

        Int16 bodyLength = BitConverter.ToInt16(state.readBuff, 0);
        //消息体长度
        if (buffCount < 2 + bodyLength)
            return;
        //如果是完整的消息,就处理它
        string s = System.Text.Encoding.UTF8.GetString(state.readBuff, 2, buffCount);
        //使用System.Text.Encoding.UTF8.GetString(缓冲区,开始位置,长度)将缓冲区的指定数据转换为字符串,读取消息内容。
        string recvStr = s;
        string[] split = recvStr.Split(|);
        Console.WriteLine("Recv" + recvStr);
        string msgName = split[0];
        string msgArgs = split[1];
        string funName = "Msg" + msgName;
        MethodInfo mi = typeof(MsgHandler).GetMethod(funName);
        object[] o = { state, msgArgs };
        mi.Invoke(null, o);

        //更新缓冲区
        int start = 2 + bodyLength;
        int count = buffCount - start;
        Array.Copy(state.readBuff, start, state.readBuff, 0, count);
        buffCount -= start;
        //如果有更多消息,就处理它
        if (state.readBuff.Length > 2)
        {
            DealWithMsg(state,buffCount);
        }
    }
}

MsgHandler.cs

using System;
using System.Collections.Generic;
class MsgHandler
{
    public static void MsgEnter(ClientState c,string msgArgs)
    {
        //解析参数
        string[] split = msgArgs.Split(,);
        string desc = split[0];
        float x = float.Parse(split[1]);
        float y = float.Parse(split[2]);
        float z = float.Parse(split[3]);
        float eulY = float.Parse(split[4]);
        //赋值
        c.hp = 100;
        c.x = x;
        c.y = y;
        c.z = z;
        c.eulY = eulY;
        //广播
        string sendStr = "Enter|" + msgArgs;
        foreach(ClientState cs in MainClass.clients.Values)
        {
            MainClass.Send(cs,sendStr);
        }
                                           
        Console.WriteLine("MsgEnter" + sendStr);
  }
    public static void MsgList(ClientState c,string msgArgs)
    {
            
        string sendStr = "List|";
        foreach(ClientState cs in MainClass.clients.Values)
        {
            sendStr += cs.socket.RemoteEndPoint.ToString()+",";
            sendStr += cs.x.ToString()+",";
            sendStr += cs.y.ToString()+",";
            sendStr += cs.z.ToString()+",";
            sendStr += cs.eulY.ToString()+",";
            sendStr += cs.hp.ToString()+ ",";
        }
        MainClass.Send(c,sendStr);
        Console.WriteLine(c.socket.RemoteEndPoint.ToString()+","+"MsgList" + sendStr);
  }
    public static void MsgMove(ClientState c,string msgArgs)
    {
        //解析参数
        string[] split = msgArgs.Split(,);
        string desc = split[0];
        float x = float.Parse(split[1]);
        float y = float.Parse(split[2]);
        float z = float.Parse(split[3]);
      //赋值
      c.x = x;
      c.y = y;
      c.z = z;
      //广播
        string sendStr = "Move|" + msgArgs;
        foreach(ClientState cs in MainClass.clients.Values)
        {
            MainClass.Send(cs,sendStr);
        }
    }
    public static void MsgAttack(ClientState c,string msgArgs)
    {
        //广播
        string sendStr = "Attack|" + msgArgs;
        foreach(ClientState cs in MainClass.clients.Values)
        {
            MainClass.Send(cs,sendStr);
      }
    }
    public static void MsgHit(ClientState c,string msgArgs)
    {
        //解析参数
        string[] split = msgArgs.Split(,);
        string attDesc = split[0];
        string hitDesc = split[1];
        //找出被攻击的角色
        ClientState hitCS = null;
        foreach(ClientState cs in MainClass.clients.Values)
        {
            if(cs.socket.RemoteEndPoint.ToString()== hitDesc)
            hitCS = cs;
      }
        if(hitCS == null)return;
      //扣血
      hitCS.hp -= 25;
        //死亡
        if(hitCS.hp <= 0)
        {
            string sendStr = "Die|" + hitCS.socket.RemoteEndPoint.ToString();
            foreach(ClientState cs in MainClass.clients.Values)
            {
                MainClass.Send(cs,sendStr);
        }
      }
    }
}

EventHandler.cs

using System;
public class EventHandler
{
    public static void OnDisconnect(ClientState c)
    {
        Console.WriteLine("OnDisconnect");
        string desc = c.socket.RemoteEndPoint.ToString();
        string sendStr = "Leave|" + desc + ",";
        foreach(ClientState cs in MainClass.clients.Values){
            MainClass.Send(cs,sendStr);
        }
    }
}

 

Xamarin Studio 与Socket架设简易服务器

原文:https://www.cnblogs.com/guaike01/p/14494281.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!