Step1:创建工具类 NetWorkManger 实现服务器和客户端的连接和消息的发送
创建该类需要导入命名空间: using System; using System.Net; using System.Net.Sockets; using System.Text; 将工具类设置为单例类: public class NetWorkManger { #region 单例类 private static NetWorkManger instance; private NetWorkManger () { } public static NetWorkManger Instance { get { if (instance == null) { instance = new NetWorkManger (); } return instance; } } #endregion /// <summary> /// 定义一个委托类型,只要方法类型为该类型,即可通过该委托进行自动回调(这里用在发送消息和接收回调) /// </summary> public delegate void MyCallBack (string msg);
服务器端 方法
#region 服务器端 /* * 服务器的创建流程 * 1、创建服务器 * 2、等待客户端连接 * 3、发送消息 * 4、接收消息 * * 使用到的socket中的哪些方法 * 1、创建套接字(socket)的方法 * 2、绑定端口号和IP的方法 * 3、监听连接的方法 * 4、接收客户端请求的方法(Accept) * 5、收发消息的方法 */ /// <summary> /// 服务器委托回调对象,主要向外界传送消息, /// 用作服务器向外传值 /// </summary> MyCallBack m_serverCallBack; /// <summary> /// 服务器端套接字对象 /// </summary> Socket m_serverSocket; /// <summary> /// 服务器端的输入输出缓冲区域 /// </summary> byte[] m_serverBuffer; /// <summary> /// 初始化服务器 /// </summary> /// <param name="userCallBack">外界传入的方法</param> public void ServerInit (MyCallBack userCallBack) { m_serverCallBack = userCallBack; //实例化输入输出的数组 m_serverBuffer = new byte[1024]; //实例化socket m_serverSocket = new Socket ( //使用IP地址类型为IPv4 AddressFamily.InterNetwork, //套接字类型为TCP的流式传输 SocketType.Stream, //选取协议为TCP协议 ProtocolType.Tcp ); /// <summary> /// 绑定IP地址和端口号 /// IPAddress.Any:表示接受所有连接的IP地址 /// 34567:表示端口号,IP表示是哪个电脑, /// 端口指哪个服务(哪个应用) /// </summary> IPEndPoint point = new IPEndPoint (IPAddress.Any, 34567); //将节点绑定到socket上 m_serverSocket.Bind (point); //开始监听(如果监听成功,服务器就启动成功了, //10表示能接受到的最大连接数) m_serverSocket.Listen (10); //将服务器启动成功的消息发送出去 m_serverCallBack ("服务器启动成功"); //开始接收,进入等待客户端的连接的状态 //第一个参数:这是一个方法名字,等到有客户端连接时 // 自动回调的方法,这个方法需要传入一个 // IAsyncResult类型的参数,这个方法一旦 // 开启,就会开启一个子线程,直到有人连接 // 会通知主线程,通知的内容就是这个IAsyncResult //第二个参数:对应当前监听连接的socket m_serverSocket.BeginAccept ( ServerAccept, m_serverSocket ); } /// <summary> /// 当服务器接收到用户的连接请求时的回调方法 /// </summary> /// <param name="ar">子线程向主线程传递 /// 的有客户端连接的信息</param> void ServerAccept (IAsyncResult ar) { //当客户端连接时,获取到当前子线程中等待的socket m_serverSocket = ar.AsyncState as Socket; //接收结果,这是一个新的socket Socket workingSocket = m_serverSocket.EndAccept (ar); //开始基于建立新的socket进行收发消息 workingSocket.BeginReceive ( //收发缓存区 m_serverBuffer, //起始位置 0, //接收数据的长度 m_serverBuffer.Length, //接收过程中是否包含特殊标记 SocketFlags.None, //接收到消息后的回调方法 ServerReceive, //当前的套接字状态 workingSocket ); //尾递归 m_serverSocket.BeginAccept ( ServerAccept, m_serverSocket); } /// <summary> /// 服务器接收到消息的回调方法 /// </summary> /// <param name="ar">Ar.</param> void ServerReceive (IAsyncResult ar) { Socket workingSocket = ar.AsyncState as Socket; //接收到的字节数据 int count = workingSocket.EndReceive (ar); //将字节数据转成字符串 string msgResult = UTF8Encoding.UTF8.GetString (m_serverBuffer); //回调 m_serverCallBack ("收到了" + count + "字节数据"); m_serverCallBack (msgResult); m_serverBuffer = new byte[1024]; //尾递归 workingSocket.BeginReceive ( m_serverBuffer, 0, m_serverBuffer.Length, SocketFlags.None, ServerReceive, workingSocket ); } #endregion
客户端方法封装
#region 客户端 /// <summary> /// 客户端套接字. /// </summary> Socket m_clientSocket; /// <summary> /// 客户端委托回调 /// </summary> MyCallBack m_clientCallback; /// <summary> /// 客户端数据缓存区域 /// </summary> byte[] m_clientBuffer; /// <summary> /// 客户端连接服务端的方法 /// </summary> /// <param name="ip">要连接的IP地址</param> /// <param name="port">端口号</param> /// <param name="uerCallBack">消息回调</param> public void ClientConnect ( string ip, int port, MyCallBack uerCallBack) { m_clientSocket = new Socket ( AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp ); //初始化客户端数据缓存区域 m_clientBuffer = new byte[1024]; //连接服务器,IPAddress.Parse:解析IP m_clientSocket.Connect ( IPAddress.Parse (ip), port); //消息回调 m_clientCallback = uerCallBack; m_clientCallback ("服务器连接成功"); //开始接收消息 m_clientSocket.BeginReceive ( m_clientBuffer, 0, m_clientBuffer.Length, SocketFlags.None, ClinetReceive, m_clientSocket ); } /// <summary> /// 客户端接收到消息后回调的方法 /// </summary> /// <param name="ar">Ar.</param> void ClinetReceive (IAsyncResult ar) { Socket workingSocket = ar.AsyncState as Socket; //接收到的字节数目 int count = workingSocket.EndReceive (ar); //将接收到的数据转成字符串 string msgResult = UTF8Encoding.UTF8.GetString (m_clientBuffer); m_clientCallback ("收到了" + count + "字节数据"); //对外进行回调 m_clientCallback (msgResult); //重置一下buffer m_clientBuffer = new byte[1024]; //开始接收消息(递归接收) m_clientSocket.BeginReceive ( m_clientBuffer, 0, m_clientBuffer.Length, SocketFlags.None, ClinetReceive, workingSocket ); } /// <summary> /// 客户端发送消息的方法 /// </summary> /// <param name="msg">Message.</param> public void ClientSend (string msg) { //将要发送的内容转成字节数组 m_clientBuffer = UTF8Encoding.UTF8.GetBytes (msg); //开始发送 m_clientSocket.BeginSend ( m_clientBuffer, 0, m_clientBuffer.Length, SocketFlags.None, //数据发送成功之后的回调 SendSucces, m_clientSocket ); } /// <summary> /// 客户端发送数据成功的回调方法 /// </summary> /// <param name="ar">Ar.</param> void SendSucces (IAsyncResult ar) { //发送成功,获得发送成功的socket Socket workingSocket = ar.AsyncState as Socket; //结束发送 workingSocket.EndSend (ar); } #endregion
step2:创建服务器场景-Server(接收消息)
public class ServerScript : MonoBehaviour { Text m_text; string m_currentMsg; void Awake () { //保证程序后台运行 Application.runInBackground = true; } void Start () { m_text = GameObject.Find ("Text").GetComponent<Text> (); //创建服务器 NetWorkManger.Instance.ServerInit ((string msg) => { //将服务器传递过来的数据接收一下 m_currentMsg = msg; }); m_text.text = m_currentMsg; } void Update () { //将接受到的数据放到Text中 m_text.text = m_currentMsg; }
step3:创建客户端服务器-Client(发送消息)
public class ServerScript : MonoBehaviour { Text m_text; string m_currentMsg; void Awake () { //保证程序后台运行 Application.runInBackground = true; } void Start () { m_text = GameObject.Find ("Text").GetComponent<Text> (); //创建服务器 NetWorkManger.Instance.ServerInit ((string msg) => { //将服务器传递过来的数据接收一下 m_currentMsg = msg; }); m_text.text = m_currentMsg; } void Update () { //将接受到的数据放到Text中 m_text.text = m_currentMsg; } }