C# Unity3d 5.x的简约Python服务器

C# Unity3d 5.x的简约Python服务器,c#,python,unity3d,C#,Python,Unity3d,TL;DR:我在Unity3D客户端应用程序和服务器上的UDP python侦听器之间通信时遇到问题 我试图通过Unity 5.x NetworkTransport LLAPI和Python 3.x socket模块从Unity3D游戏客户端获得一个低级调用和响应 目标: 将发送到服务器的消息反弹回客户端 问题: 当我运行Unity3d客户端时,套接字打开,服务器每秒打印一个新的recvfrom数据,但unity从未接收到反弹的数据 约10秒后,客户端收到超时错误和断开连接事件 地位: 客户

TL;DR:我在Unity3D客户端应用程序和服务器上的UDP python侦听器之间通信时遇到问题

我试图通过Unity 5.x NetworkTransport LLAPI和Python 3.x socket模块从Unity3D游戏客户端获得一个低级调用和响应

目标: 将发送到服务器的消息反弹回客户端

问题:

  • 当我运行Unity3d客户端时,套接字打开,服务器每秒打印一个新的recvfrom数据,但unity从未接收到反弹的数据
  • 约10秒后,客户端收到超时错误和断开连接事件
地位:

客户: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)
客户端统一网络类:

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>";
        }
    }
}
使用UnityEngine;
使用UnityEngine。联网;
使用系统集合;
公共类NetworkExecutor:MonoBehavior
{
常量字符串addr=IP_addr;
const int port=端口;
布尔连接=假;
//执行大量错误检查,但不需要保存它们。让我们定义并保持它。
字节e;
无效开始()
{
//一些测试包括等待响应或重复发送/接收呼叫。
//为了效率和人的理智,我们在协作中这样做。
start例程(TestNetwork());
}
IEnumerator测试网络()
{
//定义网络配置。
ConnectionConfig config=新的ConnectionConfig();
int reliableChannel=config.AddChannel(QosType.Reliable);
int maxConnections=10;
HostTopology hostTopo=新的HostTopology(配置,maxConnections);
//初始化并使用配置连接网络。
NetworkTransport.Init();
int hostId=NetworkTransport.AddHost(hostTopo);
int connectionId=NetworkTransport.Connect(主机ID、地址、端口、0、输出e);
Debug.Log(“Connect.Host ID:+hostId+”连接ID:+connectionId);
ErrStr(e);
//发送测试消息。
byte[]msg=System.Text.Encoding.UTF8.GetBytes(“发送字符串”);
NetworkTransport.Send(主机ID、连接ID、可靠通道、消息、4096、out e);
Debug.Log(“Send.Msg:+Msg”);
ErrStr(e);
//接收测试消息。
int-recHostId;
int-recConnectionId;
int-recChannelId;
int-recSize;
msg=System.Text.Encoding.UTF8.GetBytes(“未修改的字节缓冲区”);
NetworkEventType eventType=NetworkTransport.Receive(out-recHostId、out-recConnectionId、out-recChannelId、msg、4096、out-recSize、out-e);
Log(“Receive.Type:+eventType+”Msg:+System.Text.Encoding.UTF8.GetString(Msg));
Log(“(hID:+recHostId+”cID:+recConnectionId+”chId:+recChannelId+”“+recSize+”);
ErrStr(e);
NetworkTransport.Disconnect(主机ID、连接ID、输出e);
ErrStr(e);
屈服断裂;
}
字符串ErrStr(字节e)
{
交换机((网络错误)e)
{
案例网络错误。确定:
返回“Ok”;
案例NetworkError.ErrorHost:
返回“错误主机”;
案例网络错误。错误连接:
返回“错误连接”;
案例NetworkError.ErrorChannel:
返回“错误通道”;
案例NetworkError.NoResources:
返回“无资源”;
案例NetworkError.BadMessage:
返回“坏消息”;
案例网络错误。超时:
返回“超时”;
案例NetworkError.MessageToLong:
返回“消息太长”;
案例网络错误。错误操作:
返回“错误操作”;
案例NetworkError.VersionMismatch:
返回“版本不匹配”;
案例网络错误.CRCMismatch:
返回“CRC不匹配”;
案例网络错误.DNS失败:
返回“DNS失败”;
违约:
return“大问题,我们不知道此错误代码。”;
}
}
}

**请原谅这一团糟。与我的自然冲动相反,这里忽略了许多编码约定和良好实践。这是因为该应用程序仅用于理解Unity和Python最基本的底层网络用法。当可以建立一个基本信号量时,它将被丢弃并正确重写。

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

python代码使用的是标准UDP代码。您的统一代码是而不是。您使用的
NetworkTransport
API仅用于两个Unity应用程序之间的通信。这是一个LLAPI库,它是一个基于UDP的tin层。同样,它不是用于Unity和标准UDP连接之间的连接,而是用于两个Unity程序之间的连接


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

您是否检查UDP包是否确实使用
tshark
之类的工具发送和接收?检查是否使用WireShark之类的工具接收任何包。如果您看到这些包,其中一个可能的原因可能是需要响应。简单地回复回字符串可能不是有效的响应。