当前位置: 移动技术网 > IT编程>开发语言>c# > C#中Socket与Unity相结合示例代码

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

2019年07月18日  | 移动技术网IT编程  | 我要评论

前言

初步接触了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网络游戏实战》一书。

总结

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

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网