【问题标题】:Local Client/Server interaction not functioning in Unity本地客户端/服务器交互在 Unity 中不起作用
【发布时间】:2017-09-16 17:47:22
【问题描述】:

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

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;
    }
}

【问题讨论】:

  • 如果您将 IP 地址从“localhost”更改为您的实际 IP 地址会怎样?
  • @Programmer 好像没什么区别,还是没有收到反馈。

标签: c# unity3d networking


【解决方案1】:

您在 youtube 上关注该教程,在视频播放大约 20 分钟时,他更改了一行,但没有对其发表评论。

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

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

收件人:

hostID = NetworkTransport.AddHost(topo, 0);

据我所知,原因是您在使用同一台机器时需要使用不同的端口。当使用 0 时,将选择一个随机端口。

如果您仍然无法使用,请尝试进行此更改,看看是否有帮助。

Unity Docs reference

【讨论】:

    【解决方案2】:

    Unity 中有两个网络 API,分别是 LLAPI 和 HLAPI。 您当前正在使用 LLAPI。使用 LLAPI,您不能在同一台机器/设备上创建服务器和客户端。

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

    如果你不使用服务器和客户端两种不同的设备,并尝试调用NetworkTransport.AddHost函数,你会在客户端得到如下错误:

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

    另外,如果NetworkTransport.AddHost 失败并调用NetworkTransport.Connect,你也会得到另一个错误:

    host id out of bound id {-1} max id 应该大于 0 并且小于 {0}


    如果您不介意使用 HLAPI 而不是 LLAPI,您实际上可以通过使用 NetworkManager.StartHost() 函数来摆脱限制,该函数允许您在同一应用程序上启动服务器和客户端。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-12-25
      • 2016-07-28
      • 1970-01-01
      • 2017-12-06
      • 1970-01-01
      • 1970-01-01
      • 2014-10-06
      • 2015-08-14
      相关资源
      最近更新 更多