2016-07-29 45 views
1

TL; DR:我在服務器上的Unity3D客戶端應用程序和UDP python偵聽器之間進行通信時遇到問題。Minimalist Python Server for Unity3d 5.x

我想簡單地得到一個低級別從通過Unity 5.x的NetworkTransport LLAPI和Python 3.x的插座模塊Unity3D遊戲客戶端的呼叫和應答

目標: 彈跳發送消息到服務器回到客戶端。

問題:

  • 打開了套接字和服務器顯示新的recvfrom的數據每一秒,當我運行Unity3d客戶端,但團結永遠不會收到退回的數據。
  • 大約10秒後,客戶端收到Timeout錯誤以及DisconnectEvent。

狀態:

客戶:統一5.4

服務器:亞馬遜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>"; 
     } 
    } 
} 

**原諒這個爛攤子。違揹我自然的要求,這裏忽略了許多編碼習慣和良好做法。這是因爲該應用僅用於瞭解Unity和Python最基本的低級網絡使用情況。當可以建立原始信號量時,這將被丟棄並被正確地重寫。

+0

你有沒有檢查UDP包是否真的用'tshark'這樣的工具發送和接收? –

+0

檢查您是否收到帶有WireShark等工具的任何軟件包。如果您看到包裹,可能的原因之一可能是需要回復。簡單回覆字符串可能不是有效的迴應。 – Joshua

回答

4

UDPTCP都是標準協議。這意味着無論您使用哪種編程語言,他們都應該能夠相互溝通。

你的Python代碼使用標準的UDP代碼。你的Unity代碼是而不是。您使用的NetworkTransport API僅用於兩個Unity應用程序之間的通信。它是一個LLAPI庫,它是一個建立在UDP之上的錫層。再次,它是而不是意味着用於Unity和標準UDP連接之間的連接,但是在兩個Unity程序之間。

要與您的python UDP代碼進行通信,您必須在您的C#代碼中使用來自System.Net.Sockets名稱空間的UdpClient類。以下是Unity中UDP代碼的example