简体   繁体   English

Unity3D C# 的 LAN 通信

[英]LAN communication for Unity3D C#

I would like to make 2 computers communicate over the LAN using Unity without 3rd party plugins.我想让 2 台计算机在没有 3rd 方插件的情况下使用 Unity 通过 LAN 进行通信。 I have found some code that works for localhost but when I execute the server on one PC and the client on the other I can not get it to work.我找到了一些适用于 localhost 的代码,但是当我在一台 PC 上执行服务器并在另一台 PC 上执行客户端时,我无法让它工作。

Here is the code I currently use:这是我目前使用的代码:

The server:服务器:

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

public class Server: MonoBehaviour
{
    private TcpListener tcpListener;    
    private Thread tcpListenerThread;
    private TcpClient connectedTcpClient;

    void Start()
    {
        tcpListenerThread = new Thread(new ThreadStart(ListenForIncomingRequests));
        tcpListenerThread.IsBackground = true;
        tcpListenerThread.Start();
    }

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            SendMessage();
        }
    }

    private void ListenForIncomingRequests()
    {
        try
        {
            tcpListener = new TcpListener(IPAddress.Any, 8052);
            tcpListener.Start();
            Debug.Log("Server is listening");
            Byte[] bytes = new Byte[1024];
            while (true)
            {
                using (connectedTcpClient = tcpListener.AcceptTcpClient())
                {
                    using (NetworkStream stream = connectedTcpClient.GetStream())
                    {
                        int length;
                        while ((length = stream.Read(bytes, 0, bytes.Length)) != 0)
                        {
                            var incomingData = new byte[length];
                            Array.Copy(bytes, 0, incomingData, 0, length);
                            string clientMessage = Encoding.ASCII.GetString(incomingData);
                            Debug.Log("client message received as: " + clientMessage);
                        }
                    }
                }
            }
        }
        catch (SocketException socketException)
        {
            Debug.Log("SocketException " + socketException.ToString());
        }

        Debug.Log("Exiting...");
    }

    private void SendMessage()
    {
        if (connectedTcpClient == null)
        {
            return;
        }

        try
        {
            NetworkStream stream = connectedTcpClient.GetStream();
            if (stream.CanWrite)
            {
                string serverMessage = "This is a message from your server.";
                byte[] serverMessageAsByteArray = Encoding.ASCII.GetBytes(serverMessage);
                stream.Write(serverMessageAsByteArray, 0, serverMessageAsByteArray.Length);
                Debug.Log("Server sent his message - should be received by client");
            }
        }
        catch (SocketException socketException)
        {
            Debug.Log("Socket exception: " + socketException);
        }
    }
}

The client:客户端:

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

public class Client : MonoBehaviour
{
    #region private members     
    private TcpClient socketConnection;
    private Thread clientReceiveThread;
    #endregion
    // Use this for initialization  
    void Start()
    {
        ConnectToTcpServer();
    }
    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            SendMessage();
        }
    }
    /// <summary>   
    /// Setup socket connection.    
    /// </summary>  
    private void ConnectToTcpServer()
    {
        try
        {
            clientReceiveThread = new Thread(new ThreadStart(ListenForData));
            clientReceiveThread.IsBackground = true;
            clientReceiveThread.Start();
        }
        catch (Exception e)
        {
            Debug.Log("On client connect exception " + e);
        }
    }
    /// <summary>   
    /// Runs in background clientReceiveThread; Listens for incoming data.  
    /// </summary>     
    private void ListenForData()
    {
        try
        {
            socketConnection = new TcpClient("192.168.1.8", 8052);
            Byte[] bytes = new Byte[1024];
            while (true)
            {
                // Get a stream object for reading              
                using (NetworkStream stream = socketConnection.GetStream())
                {
                    int length;
                    // Read incoming stream into byte array.
                    while ((length = stream.Read(bytes, 0, bytes.Length)) != 0)
                    {
                        var incomingData = new byte[length];
                        Array.Copy(bytes, 0, incomingData, 0, length);
                        // Convert byte array to string message.                        
                        string serverMessage = Encoding.ASCII.GetString(incomingData);
                        Debug.Log("server message received as: " + serverMessage);
                    }
                }
            }
        }
        catch (SocketException socketException)
        {
            Debug.Log("Socket exception: " + socketException);
        }

        Debug.Log("Exiting...");
    }
    /// <summary>   
    /// Send message to server using socket connection.     
    /// </summary>  
    private void SendMessage()
    {
        if (socketConnection == null)
        {
            return;
        }
        try
        {
            // Get a stream object for writing.             
            NetworkStream stream = socketConnection.GetStream();
            if (stream.CanWrite)
            {
                string clientMessage = "This is a message from one of your clients.";
                // Convert string message to byte array.                 
                byte[] clientMessageAsByteArray = Encoding.ASCII.GetBytes(clientMessage);
                // Write byte array to socketConnection stream.                 
                stream.Write(clientMessageAsByteArray, 0, clientMessageAsByteArray.Length);
                Debug.Log("Client sent his message - should be received by server");
            }
        }
        catch (SocketException socketException)
        {
            Debug.Log("Socket exception: " + socketException);
        }
    }
}

When I run the client I get this error: A connection attempt failed because the connected party did not properly respond after a period of time or connected host has failed to respond运行客户端时出现此错误:连接尝试失败,因为连接方在一段时间后没有正确响应或连接的主机未能响应

I also tried allowing the port on the firewall on both computers but it also didn't work.我还尝试在两台计算机上允许防火墙上的端口,但它也不起作用。

What am I missing?我错过了什么?

Thank you, Nick谢谢你,尼克

I will add the solution here for anyone that has the same issue as I had.我将在此处为与我遇到相同问题的任何人添加解决方案。

Unity Editor automatically adds a firewall rule that blocks the connections , you need to disable this rule, or set it to "Allow the connection if it is secure". Unity Editor 会自动添加阻止连接的防火墙规则,您需要禁用此规则,或将其设置为“如果连接安全则允许连接”。

For those that are not sure how to set the firewall rules here are the steps that I took and it worked (windows 10).对于那些不确定如何在此处设置防火墙规则的人,这是我采取的步骤并且它有效(Windows 10)。

Click start, type "firewall" then click on "Windows defender firewall with advanced security", click "Inbound Rules", search for the rule with the red block sign in front of it called "Unity {your version} Editor" and double click it, set the Action to "Allow the connection if it is secure" or just disable it.点击开始,输入“防火墙”,然后点击“Windows Defender 高级安全防火墙”,点击“入站规则”,搜索前面有红色块符号的规则,名为“Unity {您的版本}编辑器”并双击它,将操作设置为“如果它是安全的,则允许连接”或只是禁用它。 Then you will also need to create a new rule allowing the connection from the specific editor at the specific port.然后,您还需要创建一个新规则,允许来自特定编辑器在特定端口的连接。

Keep in mind to use the Resource Monitor to check what is going on with the connection.请记住使用资源监视器来检查连接的情况。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM