Search Unity

Super simple UDP server example?

Discussion in 'Multiplayer' started by bigkahuna, Feb 23, 2011.

  1. bigkahuna

    bigkahuna

    Joined:
    Apr 30, 2006
    Posts:
    5,434
    Could someone post a super simple UDP server example script, preferably in Javascript? I'm trying to pass data from my Unity application to an external Windows application. The data is simply a text string (about 30 characters) that I will send once per second. It's been recommended that it would be easiest if I used UDP. I'm having a real hard time getting my head around this so a simple example would be tons of help. Thanks!
     
  2. bigkahuna

    bigkahuna

    Joined:
    Apr 30, 2006
    Posts:
    5,434
    Bumpity - bump?
     
  3. Quietus2

    Quietus2

    Joined:
    Mar 28, 2008
    Posts:
    2,058
    Hello Kahuna!

    A server or a client are both quite easy to implement involving only a couple classes. They probably suggested UDP to you as it's connectionless and makes sense for a local machine setup, the localhost loop is quite reliable, but tbqh a TCP setup isn't that much more difficult.

    If you search google for "C# UDP Server" you'll find an ocean of examples that you can use in Unityscript or whatever language you're writing your Windows standalone client in.

    http://www.java2s.com/Code/CSharp/Network/SimpleUdpServer.htm
     
  4. bigkahuna

    bigkahuna

    Joined:
    Apr 30, 2006
    Posts:
    5,434
    Hi Quietus! :)

    Your google skills are far better honed than mine, that looks like an excellent example, thanks!
     
  5. oxl

    oxl

    Joined:
    Nov 21, 2008
    Posts:
    325
  6. bigkahuna

    bigkahuna

    Joined:
    Apr 30, 2006
    Posts:
    5,434
    Thanks oxl, I tried that script but decided I needed something even simpler as I really don't know anything about networking (and almost nothing about C#).
     
  7. oxl

    oxl

    Joined:
    Nov 21, 2008
    Posts:
    325
    Ooops, you were looking for a JS example . Didn't actually read this, sorry.

    --
    oxl
     
  8. bigkahuna

    bigkahuna

    Joined:
    Apr 30, 2006
    Posts:
    5,434
    No worries oxl, any help is always appreciated. ;)
     
  9. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    The code there though requires only requires syntax updates and will then work on unityscript without any problem. (syntax update means using -> import private void etc -> function, type varname = var varName : type)

    The problem with "simple" is that UDP then is the wrong path to take because UDP is pretty complex the moment you want to go further than you host it and setup your firewall due to the required NAT punchthrough and other issues and specifics you have to keep in mind.

    Before going to this "0" level, I would consider looking at lidgren and only go with raw udp sockets if you need something that not even lidgren can fullfill for ya
     
  10. Quietus2

    Quietus2

    Joined:
    Mar 28, 2008
    Posts:
    2,058
    The OP was looking for interprocess communications on a local machine. No firewalls, NAT translation, routers or interwebs involved.
     
  11. bigkahuna

    bigkahuna

    Joined:
    Apr 30, 2006
    Posts:
    5,434
    Quietus is right. What I was looking for was a simple way to "broadcast" a short text string about once per second to another Windows application (both apps will reside on the same machine). The Windows app's developer recommended I look at using UDP so that prompted my search.
     
  12. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    args my error :(
    *hands himself over the stupid being award*


    For this kind of usage UDP indeed might be the best approach.
    Also at 1 message a second you do not even need threading.
     
  13. bigkahuna

    bigkahuna

    Joined:
    Apr 30, 2006
    Posts:
    5,434
    So would the example Quietus linked work for what I want to do?
     
  14. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
  15. bigkahuna

    bigkahuna

    Joined:
    Apr 30, 2006
    Posts:
    5,434
    Ok, I've started the C# to Js conversion of the script in the link, here's what I have so far:

    Code (csharp):
    1. import System;
    2. import System.Net;
    3. import System.Net.Sockets;
    4. import System.Text;
    5.  
    6. var recv : int;
    7. var data : byte[] = new byte[1024];
    8. var ipep : IPEndPoint = new IPEndPoint(IPAddress.Any, 9050);
    9. var newsock : Socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
    10.  
    11. function Main () {
    12.     newsock.Bind(ipep);
    13.     Debug.Log("Waiting for a client...");
    14.    
    15.     var sender : IPEndPoint = new IPEndPoint(IPAddress.Any, 0);
    16.     var Remote : EndPoint = (EndPoint)(sender);
    17.     //Remote = (EndPoint)(sender);
    18.  
    19.     recv = newsock.ReceiveFrom(data, Remote);
    20.    
    21.     Debug.Log("Message received from {0}:" + Remote.ToString());
    22.     Debug.Log(Encoding.ASCII.GetString(data, 0, recv));
    23.    
    24.     var welcome : String = "Welcome to my test server";
    25.     data = Encoding.ASCII.GetBytes(welcome);
    26.     newsock.SendTo(data, data.Length, SocketFlags.None, Remote);
    27. }
    28.  
    29. function SendSocket () {
    30.     data = new byte[1024];
    31.     recv = newsock.ReceiveFrom(data, Remote);
    32.     Debug.Log(Encoding.ASCII.GetString(data, 0, recv));
    33.     newsock.SendTo(data, recv, SocketFlags.None, Remote);
    34. }
    I'm not sure that I'm going in the right direction on this though, could someone take a look and tell me if it's looking OK? This script is still giving me an error that "Cannot create instance of abstract class 'System.Net.EndPoint'". Any suggestions? Any other errors you can see?
     
    Last edited: Feb 25, 2011
  16. bigkahuna

    bigkahuna

    Joined:
    Apr 30, 2006
    Posts:
    5,434
    Ok, no love for that question so let me ask this instead: I'm trying the C# version of that sample script instead. I've edited it so it doesn't give me any errors in the Unity editor, but it still doesn't appear to be working (I should see the "Welcome" message on the client, right?). Any ideas?

    Code (csharp):
    1. using UnityEngine;
    2. using System;
    3. using System.Net;
    4. using System.Net.Sockets;
    5. using System.Text;
    6.  
    7. public class SimpleUdpSrvr : MonoBehaviour {
    8.     public static void Main() {
    9.         int recv;
    10.         byte[] data = new byte[1024];
    11.         IPEndPoint ipep = new IPEndPoint(IPAddress.Any, 9050);
    12.    
    13.         Socket newsock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
    14.  
    15.         newsock.Bind(ipep);
    16.         Debug.Log("Waiting for a client...");
    17.  
    18.         IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
    19.         EndPoint Remote = (EndPoint)(sender);
    20.  
    21.         recv = newsock.ReceiveFrom(data, ref Remote);
    22.  
    23.         Debug.Log("Message received from {0}:" + Remote.ToString());
    24.         Debug.Log(Encoding.ASCII.GetString(data, 0, recv));
    25.  
    26.         string welcome = "Welcome to my test server";
    27.         data = Encoding.ASCII.GetBytes(welcome);
    28.         newsock.SendTo(data, data.Length, SocketFlags.None, Remote);
    29.         while(true) {
    30.             data = new byte[1024];
    31.             recv = newsock.ReceiveFrom(data, ref Remote);
    32.        
    33.             Debug.Log(Encoding.ASCII.GetString(data, 0, recv));
    34.             newsock.SendTo(data, recv, SocketFlags.None, Remote);
    35.         }
    36.     }
    37. }
    FWIW, the client is set to listen at 127.0.0.1 / 9050.
     
  17. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    Given the client code works correctly and is running before the server runs (as the server sends it only once before it enters the loop) and given you parse the data you get back to string from its ASCII nature, you should see "welcome to my test sever" yes.
     
  18. bigkahuna

    bigkahuna

    Joined:
    Apr 30, 2006
    Posts:
    5,434
    argh I can't get this to work :confused: One more try:

    Here's an even simpler Udp server example I found and converted for Unity:

    Code (csharp):
    1. using UnityEngine;
    2. using System;
    3. using System.Net;
    4. using System.Net.Sockets;
    5. using System.Text;
    6.  
    7. public class UdpSrvrSample : MonoBehaviour {
    8.     public static void Main() {
    9.         byte[] data = new byte[1024];
    10.         IPEndPoint ipep = new IPEndPoint(IPAddress.Any, 9050);
    11.         UdpClient newsock = new UdpClient(ipep);
    12.  
    13.         Debug.Log("Waiting for a client...");
    14.  
    15.         IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
    16.  
    17.         data = newsock.Receive(ref sender);
    18.  
    19.         Debug.Log("Message received from {0}:" + sender.ToString());
    20.         Debug.Log(Encoding.ASCII.GetString(data, 0, data.Length));
    21.  
    22.         string welcome = "Welcome to my test server";
    23.         data = Encoding.ASCII.GetBytes(welcome);
    24.         newsock.Send(data, data.Length, sender);
    25.  
    26.         while(true)
    27.         {
    28.             data = newsock.Receive(ref sender);
    29.        
    30.             Debug.Log(Encoding.ASCII.GetString(data, 0, data.Length));
    31.             newsock.Send(data, data.Length, sender);
    32.         }
    33.     }
    34. }
    Here's my conversion (so far) to Unityscript:

    Code (csharp):
    1. import System;
    2. import System.Net;
    3. import System.Net.Sockets;
    4. import System.Text;
    5.  
    6. function Main() {
    7.     var udata : byte[] = new byte[1024];
    8.     var ipep : IPEndPoint = new IPEndPoint(IPAddress.Any, 9050);
    9.     var newsock : UdpClient = new UdpClient(ipep);
    10.  
    11.     Debug.Log("Waiting for a client...");
    12.  
    13.     var sender : IPEndPoint = new IPEndPoint(IPAddress.Any, 0);
    14.  
    15.     udata = newsock.Receive(sender);
    16.  
    17.     Debug.Log("Message received from {0}:" + sender.ToString());
    18.     Debug.Log(Encoding.ASCII.GetString(udata, 0, udata.Length));
    19.  
    20.     var welcome : String = "Welcome to my test server";
    21.     udata = Encoding.ASCII.GetBytes(welcome);
    22.     newsock.Send(udata, udata.Length, sender);
    23.  
    24.     while(true) {
    25.         udata = newsock.Receive(sender);
    26.      
    27.         Debug.Log(Encoding.ASCII.GetString(udata, 0, udata.Length));
    28.         newsock.Send(udata, udata.Length, sender);
    29.     }
    30. }
    My Unityscript (obviously) doesn't work nor do I have any idea how to get it to work. Been pounding my head against this wall all morning. :p
     
    ROBYER1 likes this.
  19. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    The js one shows that you indeed have not replaced the while(true) with something that can work with unity.

    right now you basically infinite lock the whole engine.

    what you need to do is take the whole sending / receiving related part (I would make the first half feed class variables instead of in function ones) and move it into update or coroutine as mentioned far up.

    The code you converted there was for standalone console C# applications which show what they do on a very basic level but they do it very badly when it comes to actual usage as they hook 100% cpu, they do not even have thread sleep for 1 ms in for example.

    so a recommended example would be (written out of head)

    Code (csharp):
    1.  
    2.  
    3. import System;
    4. import System.Net;
    5. import System.Net.Sockets;
    6. import System.Text;
    7.  
    8. var udata : byte[];
    9. var newsock : UdpClient;
    10. var sender : IPEndPoint;
    11.  
    12. function Start() {
    13.     udata = new byte[1024];
    14.     var ipep : IPEndPoint = new IPEndPoint(IPAddress.Any, 9050);
    15.     newsock = new UdpClient(ipep);
    16.  
    17.     Debug.Log("Waiting for a client...");
    18.  
    19.     sender = new IPEndPoint(IPAddress.Any, 0);
    20. }
    21.  
    22. function Update()
    23. {
    24.     udata = newsock.Receive(sender);
    25.  
    26.     Debug.Log("Message received from {0}:" + sender.ToString());
    27.     Debug.Log(Encoding.ASCII.GetString(udata, 0, udata.Length));
    28.  
    29.     var welcome : String = "Welcome to my test server";
    30.     udata = Encoding.ASCII.GetBytes(welcome);
    31.     newsock.Send(udata, udata.Length, sender);
    32.  
    33. }
    34.  
    I assume the UdpSvr would be a real console .NET application that you run or part of another application thats native .net or alike, in which case I would have something continously call that, bind it to a timer that does or push it in an own thread where you use thread sleep for 1 ms
     
  20. bigkahuna

    bigkahuna

    Joined:
    Apr 30, 2006
    Posts:
    5,434
    Thanks dreamora, PM sent...
     
  21. arturmandas

    arturmandas

    Joined:
    Sep 29, 2012
    Posts:
    240
    Nice one, thanks!