好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

C#中Socket与Unity相结合示例代码

前言

初步接触了Socket,现使其与Unity相结合,做成一个简单的客户端之间可以互相发送消息的一个Test。下面话不多说了,来一起看看详细的介绍吧。

方法如下:

首先,是服务端的代码。

创建一个连接池,用于存储客户端的数量。

?

using System;

using System.Net;

using System.Net.Sockets;

using System.Collections;

using System.Collections.Generic;

 

 

namespace Server

{

  /// <summary>

  /// 对象池

  /// </summary>

  public class Conn

  {

   //常量,用于表示传输的字节最大数量,最大接收的字节数

   public const int buffer_Size = 1024;

 

   //Socket

   public Socket socket;

 

   //是否连接

   public bool isUse = false ;

 

   //传输数组,用来存储接受到的数据

   public byte [] readBuff = new byte [buffer_Size];

 

 

   public int buffCount = 0;

 

   /// <summary>

   /// 构造函数

   /// </summary>

   public Conn()

   {

    readBuff = new byte [buffer_Size];

   }

 

   /// <summary>

   /// 初始化

   /// </summary>

   /// <param name="socket"></param>

   public void Init(Socket socket)

   {

    this .socket = socket;

    isUse = true ;

    buffCount = 0;

   }

 

   /// <summary>

   /// 缓冲区剩下的字节数

   /// </summary>

   /// <returns></returns>

   public int BuffRemain()

   {

    return buffer_Size - buffCount;

   }

 

   /// <summary>

   /// 获得客户端地址

   /// </summary>

   /// <returns></returns>

   public string GetAdress()

   {

    if (!isUse)

    {

     return "无法获得地址" ;

    }

    else

    {

     return socket.RemoteEndPoint.ToString();

    }

 

   }

 

   /// <summary>

   /// 关闭连接

   /// </summary>

   public void Close()

   {

    if (!isUse)

    {

     return ;

 

    }

    else

    {

     Console.WriteLine( "断开连接" + GetAdress());

     socket.Close();

     isUse = false ;

    }

   }

  }

}

对象池创建完成后,需要在创建一个连接类,用来维护客户端的连接。

?

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Net;

using System.Net.Sockets;

 

 

namespace Server

{

  class Serv

  {

   //监听套接字

   public Socket listenfd;

 

   //客户端链接

   public Conn[] conns;

 

   //最大的连接数量

   public int maxConn = 50;

 

   //获取链接池索引,返回负数表示获取失败

   public int NewIndex()

   {

    if (conns== null )

    {

     return -1;

    }

    for ( int i = 0; i < conns.Length;i++ )

    {

     if (conns[i]== null )

     {

      conns[i] = new Conn();

      return i;

     } else if (conns[i].isUse== false )

     {

      return i;

     }

    }

    return -1;

   }

 

   //开启一个服务器

   public void Start( string host, int port)

   {

    conns = new Conn[maxConn];

 

 

    for ( int i = 0; i < maxConn;i++ )

    {

     conns[i] = new Conn();

    }

 

 

    listenfd = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

 

    IPAddress ipAdr = IPAddress.Parse(host);

    IPEndPoint ipEp = new IPEndPoint(ipAdr, port);

 

    //与一个本地终结点相关联

    listenfd.Bind(ipEp);

 

    //监听

    listenfd.Listen(maxConn);

 

    listenfd.BeginAccept(AcceptCb, listenfd);

 

   }

 

   //AcceptCb回调

   public void AcceptCb(IAsyncResult ar)

   {

    try

    {

     Socket sSocket = ar.AsyncState as Socket;

     Socket socket = sSocket.EndAccept(ar);

 

     int index = NewIndex();

     if (index<0)

     {

      socket.Close();

      Console.WriteLine( "连接已满" );

     }

     else

     {

      Conn conn = conns[index];

      conn.Init(socket);

      string adr = conn.GetAdress();

      Console.WriteLine( "客户端连接[" + adr + "Conn池ID: " + index);

 

      conn.socket.BeginReceive(conn.readBuff, conn.buffCount, conn.BuffRemain(), SocketFlags.None, ReceiveCb, conn);

 

     }

 

     listenfd.BeginAccept(AcceptCb, listenfd);

 

 

    } catch (SocketException ex)

    {

     Console.WriteLine(ex);

    }

 

   }

 

   //ReceiveCb回调

   public void ReceiveCb(IAsyncResult ar)

   {

    Conn conn = (Conn)ar.AsyncState;

    try

    {

     int count = conn.socket.EndReceive(ar);

     if (count<=0)

     {

      Console.WriteLine( "收到:" + conn.GetAdress() + "断开连接" );

      conn.Close();

      return ;

     }

     string str = Encoding.UTF8.GetString(conn.readBuff,0,count);

     Console.WriteLine( "接收到[" + conn.GetAdress() + "]数据" + str);

 

     byte [] bytes = Encoding.UTF8.GetBytes(str);

 

     for ( int i = 0; i < conns.Length;i++ )

     {

      if (conns[i]== null )

       continue ;

 

      if (!conns[i].isUse)

       continue ;

      Console.WriteLine( "将消息传送给" + conns[i].GetAdress());

      conns[i].socket.Send(bytes);

     }

     conn.socket.BeginReceive(conn.readBuff, conn.buffCount, conn.BuffRemain(), SocketFlags.None,ReceiveCb, conn);

 

    }

    catch (SocketException ex)

    {

     Console.WriteLine(ex);

     Console.WriteLine( "收到:" + conn.GetAdress() + "断开连接" );

     conn.Close();

    }

 

   }

  }

}

最后是创建一个Unity的工程,搭建一个简单的页面,通过下面的代码你可以了解需要哪些组件

?

using UnityEngine;

using System.Collections;

using System.Net;

using System.Net.Sockets;

using UnityEngine.UI;

using System.Collections.Generic;

using System;

 

public class net : MonoBehaviour

{

  //ip和端口

  public InputField hostInput;

  public InputField portInput;

 

  //显示客户端接受的消息

  public Text recvText;

  public string recvStr;

 

  //显示客户端IP和端口

  public Text clientText;

 

  //聊天输入框

  public InputField TextInput;

 

  Socket socket;

 

  const int buffer_Size = 1024;

  public byte [] readBuff = new byte [buffer_Size];

 

 

  void FixedUpdate()

  {

   recvText.text = recvStr;

  }

 

 

  //连接服务器(需要一个Button触发)

  public void Connetion()

  {

   recvText.text = "" ;

 

   socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

 

   string host = hostInput.text;

   int port = int .Parse(portInput.text);

 

   socket.Connect(host, port);

   clientText.text = "客户端地址:" +socket.LocalEndPoint.ToString();

   socket.BeginReceive(readBuff, 0, buffer_Size, SocketFlags.None, ReceiveCb,socket);

 

  }

 

  /// <summary>

  /// 接受数据

  /// </summary>

  /// <param name="ar"></param>

  public void ReceiveCb(IAsyncResult ar)

  {

  

   try

   {

    int count = socket.EndReceive(ar);

 

    string str = System.Text.Encoding.UTF8.GetString(readBuff, 0, count);

 

    if (recvStr.Length > 300) recvStr = "" ;

 

    recvStr += socket.LocalEndPoint.ToString()+str + "\n" ;

    Debug.Log( "12346" );

    socket.BeginReceive(readBuff, 0, buffer_Size, SocketFlags.None, ReceiveCb, socket);

   } catch (SocketException ex)

   {

    Debug.Log(ex);

   }

  }

 

  /// <summary>

  /// 发送数据,(需要一个Button触发)

  /// </summary>

  public void Send()

  {

   string str = TextInput.text;

   byte [] tex = System.Text.Encoding.UTF8.GetBytes(str);

   try

   {

    socket.Send(tex);

  

   }

   catch (SocketException ex)

   {

    Debug.Log(ex);

   }

  }

}

以上内容出自罗培羽老师《unity3d网络游戏实战》一书。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对服务器之家的支持。

dy("nrwz");

查看更多关于C#中Socket与Unity相结合示例代码的详细内容...

  阅读:44次