Search Unity

UDP Connection from Python possible?

Discussion in 'Multiplayer' started by MikeHibbert, Jan 26, 2016.

  1. MikeHibbert

    MikeHibbert

    Joined:
    Feb 21, 2013
    Posts:
    9
    Hi All

    I've setup a UDP socket/host on 127.0.0.1:8008 and written a small unity3d program that sends a message to the 'server' app. This works.

    However, I want to send UDP messages from my Python code and when I've attempted to do this its refusing the connection.

    I want to use python code to send commands to my app to cause things to happen in my simulation.

    Is there a protocol to connecting? or any security issues I need to code for?

    Thanks in advance!

    Mike
     
  2. Jamster

    Jamster

    Joined:
    Apr 28, 2012
    Posts:
    1,102
    Well UDP is a connectionless protocol so I'm not sure how you're managing get a refused connection...

    Python code? Unity code? What platform are you building?
     
  3. MikeHibbert

    MikeHibbert

    Joined:
    Feb 21, 2013
    Posts:
    9
    I'm building a application with Unity3d that I want to then send messages to from a Python library I'm building that will send them via UDP.
     
  4. Jamster

    Jamster

    Joined:
    Apr 28, 2012
    Posts:
    1,102
    Maybe I wasn't clear, I meant can you attach your python and Unity code, that way we can look through it and help :)
     
  5. MikeHibbert

    MikeHibbert

    Joined:
    Feb 21, 2013
    Posts:
    9
    Ok so in my unity3d app I have this server.cs script attached an object that sits an listens on 127.0.0.1:8008:

    using UnityEngine;
    using System.Collections;
    using UnityEngine.Networking;
    using System.IO;
    using System.Runtime.Serialization.Formatters.Binary;

    public class Server : MonoBehaviour
    {
    public GameObject m_text;

    public int hostId;
    public int myReiliableChannelId;

    // Use this for initialization
    void Start()
    {
    Application.runInBackground = true;
    try {
    // Network.InitializeSecurity();
    //NetworkServer.Listen(8008);
    //NetworkServer.RegisterHandler(MsgType.Connect, OnConnect);
    NetworkTransport.Init();

    ConnectionConfig config = new ConnectionConfig();
    myReiliableChannelId = config.AddChannel(QosType.Reliable);
    //int myUnreliableChannelId = config.AddChannel(QosType.Unreliable);

    HostTopology topology = new HostTopology(config, 10);

    hostId = NetworkTransport.AddHost(topology, 8008);

    Debug.Log("started server");
    } catch
    {
    Debug.Log("unable to start server");
    }
    }

    public void OnConnect(NetworkMessage netMsg)
    {
    Debug.Log(netMsg);
    }

    // Update is called once per frame
    void Update()
    {
    int recHostId;
    int connectionId;
    int channelId;
    byte[] recBuffer = new byte[1024];
    int bufferSize = 1024;
    int dataSize;
    byte error;
    NetworkEventType recData = NetworkTransport.Receive(out recHostId, out connectionId, out channelId, recBuffer, bufferSize, out dataSize, out error);



    if (dataSize > 0)
    {
    m_text.GetComponent<TextMesh>().text = recBuffer.ToString();
    Debug.Log("error: " + error.ToString());
    Debug.Log("Data size was: " + dataSize.ToString());
    Debug.Log("recBuffer: " + recBuffer.ToString());
    }

    switch (recData)
    {
    case NetworkEventType.Nothing: //1
    break;
    case NetworkEventType.ConnectEvent: //2
    Debug.Log("incoming connection event received");
    break;
    case NetworkEventType.DataEvent: //3
    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: //4
    Debug.Log("remote client event disconnected");
    break;
    }
    }

    void OnGUI()
    {
    if (GUI.Button(new Rect(10, 70, 50, 30), "Click"))
    {
    byte error;
    int connectionId = NetworkTransport.Connect(hostId, "127.0.0.1", 8008, 0, out error);
    Debug.Log("Connected to server. ConnectionId: " + connectionId);

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

    int bufferSize = 1024;

    NetworkTransport.Sed(hostId, connectionId, myReiliableChannelId, buffer, bufferSize, out error);
    }
    }
    }

    And in Python I've been using this to test sending messages across:

    import socket

    UDP_IP = "127.0.0.1"
    UDP_PORT = 8008
    MESSAGE = "Hello, World!"

    print "UDP target IP:", UDP_IP
    print "UDP target port:", UDP_PORT
    print "message:", MESSAGE

    sock = socket.socket(socket.AF_INET, # Internet
    socket.SOCK_DGRAM) # UDP
    ret = sock.sendto(MESSAGE, (UDP_IP, UDP_PORT))

    As you can see in my OnGUI() I can click a button and send a connect from there and this works, however, the connect/message attempt from the Python code doesnt and I get:

    socket.error: [Errno 10013] An attempt was made to access a socket in a way forbidden by its access permissions

    Any ideas why its not allowed?

    Mike
     
    Last edited: Jan 26, 2016
  6. Iron27

    Iron27

    Joined:
    May 5, 2014
    Posts:
    11
    Maybe related to this SO thread?
    http://stackoverflow.com/questions/...mpt-was-made-to-access-a-socket-in-a-way-forb

    On Windows Vista/7, with UAC, administrator accounts run programs in unprivileged mode by default.

    Programs must prompt for administrator access before they run as administrator, with the ever-so-familiar UAC dialog. Since Python scripts aren't directly executable, there's no "Run as Administrator" context menu option.

    It's possible to use ctypes.windll.shell32.IsUserAnAdmin() to detect whether the script has admin access, and ShellExecuteEx with the 'runas' verb on python.exe, with sys.argv[0] as a parameter to prompt the UAC dialog if needed.​