欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2023-12-13 10:22:58
前言 初步接触了socket,现使其与unity相结合,做成一个简单的客户端之间可以互相发送消息的一个test。下面话不多说了,来一起看看详细的介绍吧。 方法如下:...

前言

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

总结

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

上一篇:

下一篇: