unity Socket(局域网内才能连接上的)

34 篇文章 0 订阅
2 篇文章 0 订阅

远程需要联网的在上一篇:https://blog.csdn.net/qq_35864875/article/details/126873640?spm=1001.2014.3001.5501
这个是需要自己写服务端的局域网内使用的Socket
服务端代码:

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

namespace UnityServer
{
    class NetworkServer : MonoBehaviour
    {
        private static Socket serverSocket;
        private static byte[] buffer = new byte[1024];
        private void Awake()
        {
            Main();
        }
        static void Main()
        {
            /*创建一个socket对象*/
            //寻址方式 套接字类型 协议方式
            serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            /*绑定监听消息IP和端口号*/
            serverSocket.Bind(new IPEndPoint(IPAddress.Any, 6000));//IPAddress.Any代表本机IP
            Debug.Log("服务器端启动完成");

            /*开始监听客户端的连接请求*/
            serverSocket.Listen(100);//最多可以接收100个客户端请求

            StartAccept();//接收客户端连接

            Console.Read();//从标准输入流中读取下一个字符。当用户键入一些输入字符时,此方法基本上阻止其返回。一旦用户按ENTER键,它就会终止。

        }
        private void OnDestroy()
        {
            Close();
        }
        void Close()
        {
            serverSocket.Close();
            Debug.Log("socket关闭了");
        }

        //接收客户端连接
        static void StartAccept()
        {
            serverSocket.BeginAccept(AcceptCallback, null);
        }

        //接收客户端消息
        static void StartReceive(Socket socket)
        {
            socket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, ReceiveCallback, socket);
        }

        static void ReceiveCallback(IAsyncResult iar)
        {
            Socket socket = iar.AsyncState as Socket;

            int messgeLength = socket.EndReceive(iar);
            if (messgeLength == 0)
            {
                return;
            }
            //将接收的消息转化为string类型
            string str = Encoding.UTF8.GetString(buffer, 0, messgeLength);
            try
            {
                //代理调用主线程的方法(这个Socket 创建的是子线程无法调用到主线程的东西所以需要中介代理)
                Invoker.InvokeInMainThread(() =>
                {
                    //Debug.Log(str);//打印接收的消息
                    
                });
            }
            catch (Exception e)
            {
                Debug.Log("接收内容非字符串" + e.Message);
            }
            StartReceive(socket);//循环调用本函数,一直接收消息
        }

        static void AcceptCallback(IAsyncResult iar)
        {
            Socket socket = serverSocket.EndAccept(iar);
            Debug.Log("有个客户端连接过来了");
            Send(socket, "你好,我是服务器");
            StartReceive(socket);
            StartAccept();//循环调用本函数,一直接收客户端连接
        }

        //向客户端发消息
        static void Send(Socket socket, string str)
        {
            str = "由服务端发送:" + str;
            var date = ASCIIEncoding.UTF8.GetBytes(str);
            socket.Send(date);
        }

    }
}


客户端的代码:

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

public class NetworkClient : MonoBehaviour
{
    private Socket clientSocket;//声明Socket
    private byte[] buffer = new byte[1024];
    public static NetworkClient Ins;
    public bool IsConnected = false;//是否已连接的标识
    private void Awake()
    {
        Ins = this;
    }
    void Start()
    {
        //创建socket
        clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        //连接服务器
        IPEndPoint ip_end_point = new IPEndPoint(IPAddress.Parse("192.168.2.32"), 6000);
        try
        {
            clientSocket.Connect(ip_end_point);
            IsConnected = true;
            Debug.Log("连接服务器成功");
        }
        catch
        {
            IsConnected = false;
            Debug.Log("连接服务器失败");
            return;
        }

        //开始接收消息
        StartReceive();
        //发送一条消息给服务器
        //Send("我是客户端");
    }

    //接收消息
    void StartReceive()
    {
        clientSocket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, ReceiveCallback, null);
    }

    void ReceiveCallback(IAsyncResult iar)
    {
        int messgeLength = clientSocket.EndReceive(iar);
        if (messgeLength == 0)
        {
            return;
        }
        //将接收的消息转化为string类型
        string str = Encoding.UTF8.GetString(buffer, 0, messgeLength);
        Debug.Log(str);//打印接收的消息
        StartReceive();//循环调用本函数,一直接收消息
    }

    //发送消息
    public void Send(string str)
    {
        if (IsConnected == false)
        {
            clientSocket.Send(ASCIIEncoding.UTF8.GetBytes(str));
        }
        else
        {
            Debug.Log("客户端未连接");
        }
    }

}

最后是调用主线程的中介代码:
下面这个脚本挂载在空物体上面 同时勾选是否是服务端 脚本会根据判断Add上面俩个类

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityServer;

public class Invoker : MonoBehaviour
{
    //是否是服务端
    public bool isSocketTcpServer = true;
    public static Invoker Ins;
    public static void InvokeInMainThread(System.Action _delegate)
    { Ins.delegates.Add(_delegate); }

    public List<System.Action> delegates = new List<System.Action>();

    private void Awake()
    {
        Ins = this;
        if (isSocketTcpServer)
        {
            gameObject.AddComponent<NetworkServer>();
        }
        else
        {
            gameObject.AddComponent<NetworkClient>();
        }
    }

    void Update()
    { Execute(); }

    void Execute()
    {
        if (delegates.Count == 0)
            return;
        for (int i = 0; i < delegates.Count; i++)
            delegates[i]();
        delegates.Clear();
    }

}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值