4
\$\begingroup\$

I need a Unity3D game on Android to receive UDP packages from a Python script running on a different device.

Using System.Net is not (yet) an option, as it is only supported on Android with a valid Unity3D Pro license. That's why I try to use the Unity3D Low Level Network API (often called LLAPI).

A Unity blog post about LLAPI can be found here and the LLAPI-Documentation is here.

The problem seems to be that UDP (in general and on Python) is connection-less communication. The Unity3D LLAPI seems to use UPD (see the blog post) but it uses connection based communication.

Is it possible to write a Python script that answers the Unity3D-LLAPI-connection the right way? Does anyone have some experience with that?

My currently used test script in Unity is:

public class WiiMoteUDPTest : MonoBehaviour {

//Varibales

public int UDPlistenPort = 8876;
public string comPartnerIP = "192.168.2.122";

// The channelID for TCP
int myReliableChannelId;
int openSocketId;
int connectionId;

// Use this for initialization
void Start () {
    this.prepareConnection();
    this.connect();
}



// Update is called once per frame
void Update () {
    reveiveSocketMessage();
}


private void prepareConnection()
{
    // Initianting Unitys LowLevelAPI Network Stack
    NetworkTransport.Init();

    // Constructing a network connection config
    // This can be used for configuring the connections. Default settings should be fine thou.
    ConnectionConfig config = new ConnectionConfig();

    // Add a network channel to the connection config file bevor opening connections.
    //myReliableChannelId = config.AddChannel(QosType.Reliable);
    myReliableChannelId = config.AddChannel(QosType.Reliable);

    int maxConnections = 1;
    HostTopology topology = new HostTopology(config, maxConnections);

    // Open a Socket for communication and save the SocketID
    openSocketId = NetworkTransport.AddHost(topology, UDPlistenPort);
    Debug.Log("Socket Open. SocketId is: " + openSocketId);
}


private void connect()
{
    byte error;
    connectionId = NetworkTransport.Connect(openSocketId, comPartnerIP, UDPlistenPort, 0, out error);
    Debug.Log("Connected to server. ConnectionId: " + connectionId);
}

private void SendSocketMessage()
{
    byte error;
    byte[] buffer = new byte[1024];
    Stream stream = new MemoryStream(buffer);
    BinaryFormatter formatter = new BinaryFormatter();
    formatter.Serialize(stream, "HelloServer");

    int bufferSize = 1024;

    NetworkTransport.Send(openSocketId, connectionId, myReliableChannelId, buffer, bufferSize, out error);
}

private void reveiveSocketMessage()
{
    // Prepare the variables for receiving a network message
    int recHostId;
    int recConnectionId;
    int recChannelId;
    byte[] recBuffer = new byte[1024];
    int bufferSize = 1024;
    int dataSize;
    byte error;
    NetworkEventType recNetworkEvent = NetworkTransport.Receive(out recHostId, out recConnectionId, out recChannelId, recBuffer, bufferSize, out dataSize, out error);

    // Analyse the data of the received network message and trigger the corresponding event
    switch (recNetworkEvent)
    {
        case NetworkEventType.Nothing:
            Debug.Log("No network packege received");
            break;
        case NetworkEventType.ConnectEvent:
            Debug.Log("incoming connection event received");
            break;
        case NetworkEventType.DataEvent:
            Stream stream = new MemoryStream(recBuffer);
            BinaryFormatter formatter = new BinaryFormatter();
            string message = formatter.Deserialize(stream) as string;
            Debug.Log("incoming message event received: " + message);
            break;
        case NetworkEventType.DisconnectEvent:
            Debug.Log("remote client event disconnected");
            break;
    }

}

}

It's pretty much copied (and understood) from a blog post out there. Now the Python Code:

## Prepare the UDP-Sending:
# Set the  Port, IP-Adress and an empty message
UDP_IP = "192.168.2.133"
UDP_PORT = 8876
message = "This is a Test"

# Open the socket for the UDP communication
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.sendto(message, (UDP_IP, UDP_PORT))

This of course opens no connection but just sends a package off to a target IP at a target port. Any help is highly appreciated.

2015-10-02 EDIT:

Quite a while ago I found a solution that made it possible for me to receive UDP-Packages in Unity3D games on android. I basicaly wrote a Java/Android library myself that receives UDP based on the normal Android network stack. This library also imports the classes.jar distributed with Unity3D and uses UnityPlayer.UnitySendMessage() to send the content of the UDP packages to one of the classes I wrote in the Unity Engine. Now this solution is far from perfect as it's not really fast (UnityPlayer.UnitySendMessage() needs quite some time on every call) and it works only on Android...

I hope I will have some more time after by project to write a better documentation of what I did to make it work

\$\endgroup\$
  • \$\begingroup\$ Okay, have you tried your code to work on internet with port forwarding on router? Because, I have developed my own solution using raw socket in Unity and it worked also but the problem was, it was only working on LAN, not working over the internet. So, does your code do so? Thanks. \$\endgroup\$ – Madhusudan Sharma May 15 '18 at 16:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.