本地客户端/服务器交互在Unity中不起作用

时间:2017-09-16 17:47:23

标签: c# unity3d networking

我似乎无法让我的客户端连接到我的服务器。我正在开发一款将在局域网上播放和托管的多人游戏。我试图设置初步步骤以使所有网络传输功能继续运行,但它似乎并没有起作用。当我将客户端作为独立应用程序运行并且服务器在统一编辑器中运行时,我应该在客户端连接到服务器时在编辑器控制台中看到反馈,

case NetworkEventType.ConnectEvent:
                Debug.Log("Player " + connectionId + "has connected.");
                OnConnection(connectionId);

但我没有得到任何反馈。我是网络新手,因此我无法追踪出现问题的地方。任何帮助都会很棒!感谢。

' NetworkServerController.cs'

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
using System.Text;

public class NetworkServerController : MonoBehaviour {

    private const int MAX_CONNECTION = 100;
    private int port = 5701;

    private int hostID;
    private int webHostID;

    private int reliableChannel;
    private int unreliableChannel;
    private int reliableFragChannel;
    private int unreliableFragChannel;

    private bool isStarted = false;
    private byte error;

    private void Awake()
    {
        //NetworkServer.Reset();
    }

    private void Start()
    {
        NetworkTransport.Init();
        ConnectionConfig cc = new ConnectionConfig();

        reliableChannel = cc.AddChannel(QosType.Reliable);
        unreliableChannel = cc.AddChannel(QosType.Unreliable);
        reliableFragChannel = cc.AddChannel(QosType.ReliableFragmented);
        unreliableFragChannel = cc.AddChannel(QosType.UnreliableFragmented);

        HostTopology topo = new HostTopology(cc, MAX_CONNECTION);

        hostID = NetworkTransport.AddHost(topo, port, null);
        webHostID = NetworkTransport.AddWebsocketHost(topo, port, null);

        isStarted = true;
    }

    private void Update()
    {
        if (!isStarted)
            return;

        int recHostId;
        int connectionId;
        int channelId;
        byte[] recBuffer = new byte[1024];
        int bufferSize = 1024;
        int dataSize;
        byte error;
        NetworkEventType recData = NetworkTransport.Receive(out recHostId, out connectionId, out channelId, recBuffer, bufferSize, out dataSize, out error);
        switch (recData)
        {
            case NetworkEventType.Nothing:         //1
                break;
            case NetworkEventType.ConnectEvent:    //2
                Debug.Log("Player " + connectionId + "has connected.");
                OnConnection(connectionId);
                break;
            case NetworkEventType.DataEvent:       //3
                string msg = Encoding.Unicode.GetString(recBuffer, 0, dataSize);
                Debug.Log("Player " + connectionId + "has sent : " + msg);
                break;
            case NetworkEventType.DisconnectEvent: //4
                Debug.Log("Player " + connectionId + "has disconnected.");
                break;
        }
    }

    private void OnConnection(int cnnID)
    {
        // Add to list

        // When player joins, tell ID

        // Request name and send name of all the other players
    }
}

' NetworkClientController.cs'

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Networking;

public class NetworkClientController : MonoBehaviour {

    private const int MAX_CONNECTION = 100;
    private int port = 5701;
    private string IPAddress = "localhost";

    private int hostID;
    private int webHostID;

    private int reliableChannel;
    private int unreliableChannel;
    private int reliableFragChannel;
    private int unreliableFragChannel;

    private int connectionID;

    private float connectionTime;
    private bool isConnected = false;
    private bool isStarted = false;
    private byte error;

    private string playerName;

    private void Start()
    {
        Connect();
    }

    private void Update()
    {
        if (!isConnected)
            return;

        int recHostId;
        int connectionId;
        int channelId;
        byte[] recBuffer = new byte[1024];
        int bufferSize = 1024;
        int dataSize;
        byte error;
        NetworkEventType recData = NetworkTransport.Receive(out recHostId, out connectionId, out channelId, recBuffer, bufferSize, out dataSize, out error);
        switch (recData)
        {
            case NetworkEventType.Nothing:         //1
                break;
            case NetworkEventType.ConnectEvent:    //2
                break;
            case NetworkEventType.DataEvent:       //3
                break;
            case NetworkEventType.DisconnectEvent: //4
                break;
        }
    }

    public void Connect()
    {
        NetworkTransport.Init();
        ConnectionConfig cc = new ConnectionConfig();

        reliableChannel = cc.AddChannel(QosType.Reliable);
        unreliableChannel = cc.AddChannel(QosType.Unreliable);
        reliableFragChannel = cc.AddChannel(QosType.ReliableFragmented);
        unreliableFragChannel = cc.AddChannel(QosType.UnreliableFragmented);

        HostTopology topo = new HostTopology(cc, MAX_CONNECTION);

        hostID = NetworkTransport.AddHost(topo, port, null);
        connectionID = NetworkTransport.Connect(hostID, IPAddress, port, 0, out error);

        connectionTime = Time.time;
        isConnected = true;
    }
}

2 个答案:

答案 0 :(得分:4)

你正在youtube上关注该教程,在视频大约20分钟后他改变了一行而未对其进行评论。

在客户端脚本中更改以下行:

hostID = NetworkTransport.AddHost(topo, port, null);

要:

hostID = NetworkTransport.AddHost(topo, 0);

我收集的原因是,在使用同一台机器时需要使用不同的端口。使用0时,将选择随机端口。

如果您还没有使用它,请尝试进行此更改,看看它是否有帮助。

Unity Docs reference

答案 1 :(得分:3)

Unity中有两个网络API,即LLAPI和HLAPI。 您目前正在使用LLAPI 。使用LLAPI,您无法在同一台计算机/设备上创建服务器和客户端。

您需要两台设备才能对其进行测试。无论是两台计算机还是一台Android / iOS设备,您都可以从编辑器或计算机上的Build进行测试。服务器和客户端只需要在两台不同的机器上运行。

如果您不为服务器和客户端使用两个不同的设备并尝试调用'static函数,则客户端将收到以下错误:

  

无法在ip {*}和端口{5701}上打开套接字;请检查你的   网络,最有可能的端口已被占用

此外,如果NetworkTransport.AddHost失败且调用NetworkTransport.AddHost,您也会收到其他错误:

  

主机ID超出范围的标识{-1}最大ID应该大于0且小于   {0}

如果您不介意使用HLAPI而不是LLAPI,您可以使用NetworkTransport.Connect函数实际获得限制,该函数允许您在同一个应用程序上启动服务器和客户端。