5

我需要用本地网络中的服务器实现游戏,无法访问 Internet

假设我可以处理客户端和服务器之间的连接和网络通信(如果它们已连接),我想知道是否有一种优雅的方法可以让客户端在启动时发现服务器的地址。


我提供我的方法作为答案,以分享知识,但很高兴看看是否有更优雅/自动的方法。

4

2 回答 2

7

客户端将使用特定端口连接到游戏服务器。我在不同的端口实现了 UDP 多播,因此客户端可以获得服务器的 IP。

以下代码适用于服务器和客户端,用 Unity Javascript 编写。在服务器端,它将开始每秒在端口 5100 发送多播消息。客户端将侦听同一端口,直到它们检测到新消息。然后他们识别发件人的 IP 并以 Unity3d 的方式建立客户端-服务器连接。

private var server_port : int = 5000;
private var server_ip : String;

// multicast
private var startup_port : int = 5100;
private var group_address : IPAddress = IPAddress.Parse ("224.0.0.224");
private var udp_client : UdpClient;
private var remote_end : IPEndPoint;

function Start ()
{
    // loaded elsewhere
    if (station_id == "GameServer")
        StartGameServer ();
    else
        StartGameClient ();
}

function StartGameServer ()
{
    // the Unity3d way to become a server
    init_status = Network.InitializeServer (10, server_port, false);
    Debug.Log ("status: " + init_status);

    StartBroadcast ();
}

function StartGameClient ()
{
    // multicast receive setup
    remote_end = IPEndPoint (IPAddress.Any, startup_port);
    udp_client = UdpClient (remote_end);
    udp_client.JoinMulticastGroup (group_address);

    // async callback for multicast
    udp_client.BeginReceive (new AsyncCallback (ServerLookup), null);

    MakeConnection ();
}

function MakeConnection ()
{
    // continues after we get server's address
    while (!server_ip)
        yield;

    while (Network.peerType == NetworkPeerType.Disconnected)
    {
        Debug.Log ("connecting: " + server_ip +":"+ server_port);

        // the Unity3d way to connect to a server
        var error : NetworkConnectionError;
        error = Network.Connect (server_ip, server_port);

        Debug.Log ("status: " + error);
        yield WaitForSeconds (1);
    }
}

/******* broadcast functions *******/
function ServerLookup (ar : IAsyncResult)
{
    // receivers package and identifies IP
    var receiveBytes = udp_client.EndReceive (ar, remote_end);

    server_ip = remote_end.Address.ToString ();
    Debug.Log ("Server: " + server_ip);
}

function StartBroadcast ()
{
    // multicast send setup
    udp_client = UdpClient ();
    udp_client.JoinMulticastGroup (group_address);
    remote_end = IPEndPoint (group_address, startup_port);

    // sends multicast
    while (true)
    {
        var buffer = Encoding.ASCII.GetBytes ("GameServer");
        udp_client.Send (buffer, buffer.Length, remote_end);

        yield WaitForSeconds (1);
    }
}

将此附加到您的GameObject应该可以解决问题。

于 2013-04-19T17:09:45.657 回答
3

这是ac#版本谢谢

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

public class OwnNetworkManager : MonoBehaviour
{

private int server_port = 5000;
private string server_ip;

// multicast
private int startup_port = 5100;
private IPAddress group_address = IPAddress.Parse("127.0.0.1");
private UdpClient udp_client ;
private IPEndPoint remote_end ;


void Start()
{
    // loaded elsewhere
    if (Loader.IsPC)
        StartGameServer();
    else
        StartGameClient();
}

void StartGameServer()
{
    // the Unity3d way to become a server
    NetworkConnectionError init_status = Network.InitializeServer(10, 
server_port, false);
    Debug.Log("status: " + init_status);

    StartCoroutine(StartBroadcast());
}

void StartGameClient()
{
    // multicast receive setup
    remote_end = new IPEndPoint(IPAddress.Any, startup_port);
    udp_client = new UdpClient(remote_end);
    udp_client.JoinMulticastGroup(group_address);

    // async callback for multicast
    udp_client.BeginReceive(new AsyncCallback(ServerLookup), null);

    StartCoroutine(MakeConnection());
}

IEnumerator MakeConnection()
{
    // continues after we get server's address
    while (string.IsNullOrEmpty(server_ip))
        yield return null;

    while (Network.peerType == NetworkPeerType.Disconnected)
    {
        Debug.Log("connecting: " + server_ip + ":" + server_port);

        // the Unity3d way to connect to a server
        NetworkConnectionError error ;
        error = Network.Connect(server_ip, server_port);
        Debug.Log("status: " + error);
        yield return new WaitForSeconds (1);
    }
}

/******* broadcast functions *******/
void ServerLookup(IAsyncResult ar)
{
    // receivers package and identifies IP
    var receiveBytes = udp_client.EndReceive(ar, ref remote_end);

    server_ip = remote_end.Address.ToString();
    Debug.Log("Server: " + server_ip);
}

IEnumerator StartBroadcast()
{
    // multicast send setup
    udp_client = new UdpClient();
    udp_client.JoinMulticastGroup(group_address);
    remote_end = new IPEndPoint(group_address, startup_port);

    // sends multicast
    while (true)
    {
        var buffer = Encoding.ASCII.GetBytes("GameServer");
        udp_client.Send(buffer, buffer.Length, remote_end);

        yield return new WaitForSeconds (1);
    }
}
}
于 2018-03-06T10:10:39.353 回答