Unity学习之Socket通信


简单的一对一通信,客户端向服务器传输字符串,具体操作如下:

服务器端

在VisualStudio中创建一个新工程,在工程中编写服务器逻辑,代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;

/// <summary>
/// Socket服务器端
/// </summary>
namespace SocketServerTest
{
    
    
    class Program
    {
    
    
        private static Socket socket;
        //接收消息的载体
        private static byte[] buffer = new byte[1024];
        //服务器入口
        static void Main(string[] args)
        {
    
    
            //1,创建套接字,并设置参数
            socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //2,绑定服务器的IP和端口
            EndPoint ep = new IPEndPoint(IPAddress.Any, 9999);
            socket.Bind(ep);
            //3,监听是否有客户端进行连接
            //参数表示在同一时间内服务器可以对该数量下的客户端进行操作,超出数量,则需要进行排队
            socket.Listen(0);
            //4,应答客户端
            StartAccept();
            Console.Read();
        }

        /// <summary>
        /// 开始应答客户端
        /// </summary>
        static void StartAccept()
        {
    
    
            //异步应答客户端
            socket.BeginAccept(AcceptCallback, null);
        }

        /// <summary>
        /// 开始接收消息
        /// </summary>
        /// <param name="client">应答的客户端套接字</param>
        static void StartReceive(Socket client)
        {
    
    
            //将应答的客户端作为参数传给回调函数
            client.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, ReceiveCallback, client);
        }

        /// <summary>
        /// 应答的回调函数
        /// </summary>
        /// <param name="iar"></param>
        static void AcceptCallback(IAsyncResult iar)
        {
    
    
            //1,结束应答,获得应答的客户端的套接字(服务器端将会有多个Socket,每一个Socket对应的是其响应的客户端)
            //一对一通信,client指的是应答Socket,而非客户端本身,该Socket属于服务器端,由服务器产生,针对请求响应的客户端
            Socket client = socket.EndAccept(iar);
            //2,应答Socket接收消息
            StartReceive(client);
            //3,处理完一个,继续处理,继续应答
            StartAccept();
        }

        static void ReceiveCallback(IAsyncResult iar)
        {
    
    
            //1,从回调函数结果中获取传递过来的参数,即获取传递过来的应答客户端对象
            Socket client = iar.AsyncState as Socket;
            //2,获取接收到信息的长度
            int len = client.EndReceive(iar);
            //3,判断信息是否成功接收
            if (len == 0)
            {
    
    
                return;
            }
            //4,解析信息并处理
            string str = Encoding.UTF8.GetString(buffer, 0, len);
            Console.WriteLine(str);
            //5,继续接收来自客户端的信息
            StartReceive(client);
        }
    }
}

客户端

在unity中创建一个脚本,即Client.cs,具体代码如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Net;
using System.Net.Sockets;
using System;
using System.Text;

/// <summary>
/// 客户端
/// </summary>
public class Client : MonoBehaviour
{
    
    
    private Socket socket;
    //定义一个接收消息载体
    private byte[] buffer = new byte[1024];
    
    void Start()
    {
    
    
        //1,创建套接字 参数1表示地址族类型选择IP,参数2表示套接字类型选择数据流的方式,参数3表示协议选择TCP协议
        //协议选择UDP,套接字类型应选择数据报,即SocketType.Dgram
        socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        //2,连接服务器端
        socket.Connect("192.168.3.43", 9999);
        //3,连接服务器成功后,开始异步接收消息(第一条数据)
        StartReceive();
        //4,向服务器发送消息
        Send();
    }

    /// <summary>
    /// 开始接收消息
    /// </summary>
    void StartReceive()
    {
    
    
        //异步接收数据 参数1:接收信息载体,参数2:从0开始,参数3:信息长度,参数4:目前为空,参数5:回调函数,参数6:回调函数需要用到的参数
        //接收到的消息将在回调函数中进行处理
        socket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, ReceiveCallback, null);
    }

    /// <summary>
    /// 接收消息的回调函数
    /// </summary>
    /// <param name="iar">BeginReceive方法得到结果即为回调函数的参数</param>
    void ReceiveCallback(IAsyncResult iar)
    {
    
    
        //1,结束接收消息后,会返回接收到的消息长度
        int len = socket.EndReceive(iar);
        //2,判断消息是否被正确完整接收
        //当接收消息过程中发生中断,EndReceive一直处于接收状态,返回的消息长度为0,及消息未传输成功
        if (len == 0)
        {
    
    
            return;
        }
        //3,对接收的消息进行解析
        #region 简单消息示例,接收到的是字符串信息
        //将字节数组中的信息转换成字符串,并用UTF-8进行编码
        string str = Encoding.UTF8.GetString(buffer, 0, len);
        //输出消息
        Debug.Log(str);
        #endregion
        //4,循环接收消息并对消息进行处理(第一条数据解析完后,对后面服务器发送的消息进行处理)
        StartReceive();
    }

    /// <summary>
    /// 向服务器发送消息
    /// </summary>
    void Send()
    {
    
    
        socket.Send(Encoding.UTF8.GetBytes("你好!"));
    }
}

在Hierarchy面板中创建一个空的游戏对象,将Client脚本绑定在游戏对象上。创建的面板格式如下所示:
在这里插入图片描述

运行

先启动服务器端代码,再运行unity,即可得到下面的运行结果:
1,服务器启动后
在这里插入图片描述
2,客户端启动后,服务器收到消息
在这里插入图片描述

笔记来源

以上笔记是通过观看视频所得。

猜你喜欢

转载自blog.csdn.net/qingtian_111/article/details/127285523