Unity3d 5.x的极简Python服务器

4
TL;DR:我在Unity3D客户端应用程序和服务器上的UDP Python监听器之间出现通信问题。
我试图通过Unity 5.x NetworkTransport LLAPI和Python 3.x socket模块从Unity3D游戏客户端获取低级调用和响应。
目标:将发送到服务器的消息反弹回客户端。
问题:
1. 当我运行Unity3d客户端时,套接字打开并且服务器每秒打印一个新的recvfrom数据,但Unity从未收到反弹的数据。 2. 大约10秒后,客户端收到超时错误以及一个DisconnectEvent。
状态:
客户端:Unity 5.4
服务器:Amazon AWS,端口8888打开
服务器端Python应用程序:
import socket

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind(('', 8888))

print ('Listening on port 8888')

while True:
    data, addr = s.recvfrom(4096)

    if data:
        for i in range(0, len(data)):
            print (data[i])
        print (data, addr)
        s.sendto(data, addr)

客户端Unity网络类:
using UnityEngine;
using UnityEngine.Networking;
using System.Collections;

public class NetworkExecutor : MonoBehaviour
{
    const string addr = IP_ADDR;
    const int port = PORT;

    bool connected = false;

    // Doing lots of error checks but no need to save them. Let's def this and hold onto it.
    byte e;

    void Start ()
    {
        // Some testing involves waiting for responses or repetitious send/receive calls.
        // We do this in coroutines for both efficiency and human sanity.
        StartCoroutine(TestNetwork());
    }

    IEnumerator TestNetwork()
    {
        // Define network configurations.
        ConnectionConfig config = new ConnectionConfig();
        int reliableChannel = config.AddChannel(QosType.Reliable);
        int maxConnections = 10;
        HostTopology hostTopo = new HostTopology(config, maxConnections);

        // Initialize and connect network with config.
        NetworkTransport.Init();
        int hostId = NetworkTransport.AddHost(hostTopo);
        int connectionId = NetworkTransport.Connect(hostId, addr, port, 0, out e);

        Debug.Log("<b>Connect.</b> Host ID: " + hostId + " Connection ID: " + connectionId);
        ErrStr(e);

        // Send test message.
        byte[] msg = System.Text.Encoding.UTF8.GetBytes("Send string");
        NetworkTransport.Send(hostId, connectionId, reliableChannel, msg, 4096, out e);
        Debug.Log("<b>Send.</b> Msg: " + msg);
        ErrStr(e);

        // Receive test message.
        int recHostId;
        int recConnectionId;
        int recChannelId;
        int recSize;
        msg = System.Text.Encoding.UTF8.GetBytes("Unmodified byte buffer.");
        NetworkEventType eventType = NetworkTransport.Receive(out recHostId, out recConnectionId, out recChannelId, msg, 4096, out recSize, out e);
        Debug.Log("<b>Receive.</b> Type: " + eventType + " Msg: " + System.Text.Encoding.UTF8.GetString(msg));
        Debug.Log("(hID:" + recHostId + " cID:" + recConnectionId + " chId:" + recChannelId + " " + recSize + ")");
        ErrStr(e);

        NetworkTransport.Disconnect(hostId, connectionId, out e);
        ErrStr(e);

        yield break;
    }

    string ErrStr(byte e)
    {
        switch ((NetworkError)e)
        {
            case NetworkError.Ok:
                return "Ok";
            case NetworkError.WrongHost:
                return "<color=red>Wrong Host</color>";
            case NetworkError.WrongConnection:
                return "<color=red>Wrong Connection</color>";
            case NetworkError.WrongChannel:
                return "<color=red>Wrong Channel</color>";
            case NetworkError.NoResources:
                return "<color=red>No Resources</color>";
            case NetworkError.BadMessage:
                return "<color=red>Bad Message</color>";
            case NetworkError.Timeout:
                return "<color=red>Timeout</color>";
            case NetworkError.MessageToLong:
                return "<color=red>Message Too Long</color>";
            case NetworkError.WrongOperation:
                return "<color=red>Wrong Operation</color>";
            case NetworkError.VersionMismatch:
                return "<color=red>Version Mismatch</color>";
            case NetworkError.CRCMismatch:
                return "<color=red>CRC Mismatch</color>";
            case NetworkError.DNSFailure:
                return "<color=red>DNS Failure</color>";
            default:
                return "<color=red><b>Big problem, we don't know this error code.</b></color>";
        }
    }
}

** 请原谅混乱。为了理解Unity和Python的最基本的低级网络使用,我违背了自己的天性、许多编码规范和良好实践。当能够建立原始信号量时,这将被丢弃并重新正确编写。


你是否使用像tshark这样的工具检查UDP数据包是否实际发送和接收? - Klaus D.
检查是否已经收到了使用 WireShark 等工具的任何数据包。如果您看到这些数据包,则可能是因为需要响应。简单地回复字符串可能不是有效的响应之一。 - Joshua
1个回答

9

UDPTCP都是标准协议。这意味着无论您使用什么编程语言,它们都应该能够相互通信。

您的Python代码正在使用标准的UDP代码。您的Unity代码则不是。您使用的NetworkTransport API只用于两个Unity应用程序之间的通信。它是一个建立在UDP之上的薄层的LLAPI库。再次强调,它不能用于连接Unity和标准UDP连接之间,而是用于两个Unity程序之间的连接。

要与您的Python UDP代码通信,您必须在C#代码中使用System.Net.Sockets命名空间中的UdpClient类。这里有一个在Unity中使用UDP代码的示例


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接