Search Unity

Listen to port for another app

Discussion in 'Scripting' started by nafasso, Aug 20, 2015.

  1. nafasso

    nafasso

    Joined:
    Dec 3, 2013
    Posts:
    22
    Hello,

    Here is my problem/question.
    I am trying to make a unity program that uses an external program that I made in c++ and that sends informations through the 9999 port of localhost (both programs are supposed to run on the same machine).
    The point where I am stucked now is that I don't know how to make my Unity program to listen to that port and read the information sent by the external program.
    I was thinking about the new Unet API but it looks like it is more for mulptiplayer games than for random program (I don't need a player, a start point and stuffs like that).
    For the moment I am just trying to get the info through the port.
    Could you please give me some tips or a peace of code that I could use to make this work ?

    Thank you and sorry for my english.
     
  2. Duugu

    Duugu

    Joined:
    May 23, 2015
    Posts:
    241
  3. nafasso

    nafasso

    Joined:
    Dec 3, 2013
    Posts:
    22
    Hello,

    this looks like it could do the work but I am little bit confused on how to use it.
    Would you be able to show me some code example on how to set it and use it ? That would be amazing.

    Thank you
     
  4. Duugu

    Duugu

    Joined:
    May 23, 2015
    Posts:
    241
    Hey,

    Unfortunately I've never used it myself. But the linked article has a very good description of the steps and sample code.
    Basically you're just creating a TCP socket and send/receive data via the connection.
    The steps are:
    1. Initialize the Network Transport Layer
    2. Configure network topology
    3. Create Host
    4. Start communication (handling connections and sending/receiving messages)
    5. Shut down library after use.
    There's no complex magic in it and the article describes every step. It's easy to understand. Give it a try. :)
     
  5. nafasso

    nafasso

    Joined:
    Dec 3, 2013
    Posts:
    22
  6. nafasso

    nafasso

    Joined:
    Dec 3, 2013
    Posts:
    22
    I found a script doing exactly what I was trying to do. i just had to modify a little bit and I commented the useless parts for me.

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System;
    4. using System.Collections;
    5. using System.Net.Sockets;
    6. using System.Threading;
    7. using System.Net;
    8. using System.Collections.Generic;
    9. using System.Text;
    10.  
    11.  
    12. public class Server : MonoBehaviour
    13. {
    14.     Socket SeverSocket = null;
    15.     Thread Socket_Thread = null;
    16.     bool Socket_Thread_Flag = false;
    17.  
    18.     //for received message
    19. //    private float mouse_delta_x;
    20. //    private float mouse_delta_y;
    21. //    private bool isTapped;
    22. //    private bool isDoubleTapped;
    23. //
    24. //    public float getMouseDeltaX(){return mouse_delta_x;    }
    25. //    public float getMouseDeltaY(){return mouse_delta_y;    }
    26. //    public bool getTapped(){return isTapped;}
    27. //    public bool getDoubleTapped(){return isDoubleTapped;}
    28. //
    29. //    public void setMouseDeltaX(float dx){mouse_delta_x = dx;}
    30. //    public void setMouseDeltaY(float dy){mouse_delta_y = dy;}
    31. //    public void setTapped(bool t){isTapped = t;}
    32. //    public void setDoubleTapped(bool t){isDoubleTapped = t;}
    33. //
    34. //    private int tick =0;
    35.     //private string[] receivedMSG;
    36.     //public string[] getMsg(){return receivedMSG;    }
    37.  
    38.  
    39.     string[] stringSeparators = new string[] {"*TOUCHEND*","*MOUSEDELTA*","*Tapped*","*DoubleTapped*"};
    40.  
    41.     void Awake()
    42.     {
    43.         Socket_Thread = new Thread(Dowrk);
    44.         Socket_Thread_Flag = true;
    45.         Socket_Thread.Start();
    46.     }
    47.  
    48.     private void Dowrk()
    49.     {
    50.         //receivedMSG = new string[10];
    51.         SeverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    52.         IPEndPoint ipep = new IPEndPoint(IPAddress.Any, 9999);
    53.         SeverSocket.Bind(ipep);
    54.         SeverSocket.Listen(10);
    55.      
    56.         Debug.Log("Socket Standby....");
    57.         Socket client = SeverSocket.Accept();//client에서 수신을 요청하면 접속합니다.
    58.         Debug.Log("Socket Connected.");
    59.      
    60.         IPEndPoint clientep = (IPEndPoint)client.RemoteEndPoint;
    61.         NetworkStream recvStm = new NetworkStream(client);
    62.         //tick = 0;
    63.              
    64.         while (Socket_Thread_Flag)
    65.         {
    66.             byte[] receiveBuffer = new byte[1024 * 80];
    67.             try
    68.             {
    69.                  
    70.                 //print (recvStm.Read(receiveBuffer, 0, receiveBuffer.Length));
    71.                 if(recvStm.Read(receiveBuffer, 0, receiveBuffer.Length) == 0 ){
    72.                     // when disconnected , wait for new connection.
    73.                     client.Close();
    74.                     SeverSocket.Close();
    75.                  
    76.                     SeverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    77.                     ipep = new IPEndPoint(IPAddress.Any, 10000);
    78.                     SeverSocket.Bind(ipep);
    79.                     SeverSocket.Listen(10);
    80.                     Debug.Log("Socket Standby....");
    81.                     client = SeverSocket.Accept();//client에서 수신을 요청하면 접속합니다.
    82.                     Debug.Log("Socket Connected.");
    83.                  
    84.                     clientep = (IPEndPoint)client.RemoteEndPoint;
    85.                     recvStm = new NetworkStream(client);
    86.                  
    87.                 }else{
    88.                              
    89.  
    90.                     string Test = Encoding.Default.GetString(receiveBuffer);
    91.                     //string Test = Convert.ToBase64String(receiveBuffer);
    92.                     //Test = Test.Normalize();
    93.  
    94.  
    95.                     print (Test);
    96.                     //string[] splitMsg = Test.Split(stringSeparators,System.StringSplitOptions.RemoveEmptyEntries);
    97.                     // parsing gogo
    98.  
    99. //                    string[] splitMsg = Test.Split('*');
    100. ////                    print (splitMsg);
    101. //                    if(splitMsg.Length>1)
    102. //                    {
    103. //                        if(splitMsg[1].CompareTo("Tapped")==0){
    104. //                            print ("tap");
    105. //                            isTapped = true;
    106. //                        }else if(splitMsg[1].CompareTo("DoubleTapped")==0){
    107. //                            print ("double tap");
    108. //                            isDoubleTapped = true;
    109. //                        }else if(splitMsg[1].CompareTo("MOUSEDELTA")==0){
    110. //                            print ("move");
    111. //                            //string[] lastMsg = splitMsg[splitMsg.Length-1].Split('*');
    112. //                            mouse_delta_x = (float)Convert.ToDouble(splitMsg[2]);
    113. //                            mouse_delta_y = (float)Convert.ToDouble(splitMsg[3]);
    114. //                        }else{
    115. //                            print ("F*** :"+splitMsg[1].Length);
    116. //                          
    117. //                        }
    118. //                    }
    119. //
    120. //                    string singletap = "one";
    121. //                    string doubletap = "two";
    122. //                    if(splitMsg.Length>0){
    123. //
    124. //
    125.  
    126. //                          
    127. //                        if(lastMsg.Length>1){
    128. //                      
    129.  
    130. //
    131. //                        }else{
    132. //
    133. //                            print ("split msg : "+splitMsg[0]);
    134. //                            int tmp = (int)Convert.ToInt32(splitMsg[0]);
    135. //                            if(tmp ==1){
    136. //
    137. //                                print ("Tapped!~");
    138. //                          
    139. //                                isTapped = true;
    140. //
    141. //                            }else if(tmp ==2){
    142. //
    143. //                                print ("Double Tapped!~");
    144. //                          
    145. //                                isDoubleTapped = true;
    146. //                          
    147. //                            }else{              
    148. //
    149. //                            }
    150. //                        }
    151. //                    }else{
    152. //
    153. //                    }
    154.  
    155.                     //print (receivedMSG);
    156.  
    157.                 }
    158.              
    159.              
    160.             }
    161.          
    162.             catch (Exception e)
    163.             {
    164.                 Socket_Thread_Flag = false;
    165.                 client.Close();
    166.                 SeverSocket.Close();
    167.                 continue;
    168.             }
    169.          
    170.         }
    171.      
    172.     }
    173.  
    174.     void OnApplicationQuit()
    175.     {
    176.         try
    177.         {
    178.             Socket_Thread_Flag = false;
    179.             Socket_Thread.Abort();
    180.             SeverSocket.Close();
    181.             Debug.Log("Bye~~");
    182.         }
    183.      
    184.         catch
    185.         {
    186.             Debug.Log("Error when finished...");
    187.         }
    188.     }
    189.  
    190.  
    191. }
    192.  
    193.  
    194.  
     
  7. mitras2

    mitras2

    Joined:
    Aug 18, 2015
    Posts:
    2
    Hi nafassi

    Currently I do have the same problem as you. I need Unity to listen to UDP-Packages from a Python script i wrote.

    Now using the UNET LLAPI seens to bee no solution because of multiple reasons:

    • It's poorly documented
    I know the Blog post you mentioned earlier and tried to use it. Connecting two parts of Unity3D Software is not a problem but the entire Transport Layer API seems only to work if you have a Unity Game on both sides of the communication. There is absolutly no documentation hov to work with this if you have an external server script/software

    • It is not flexible, nor intended for standart UDP use
    The Transport Layer API (also refferd to als LLAPI or UNET API) is connection based communication on top of UDP (which is not connection based at all). One again. There is no documentation on how to establish or acknoledge a connection from a non Unity piece of software.
    I have captured the connection between two Unity test games thouh and all packages it sends for teh conncetion is completly obfuscated S***. I can't read nor decode anything of what they are doing...


    Obvisouly Unity DOES NOT WANT US TO USE LLAPI WITH FOREIGN SOFTWARE or scripts...

    Does the System.Net.Sockets based communication word good and stable for you? I have been messing with that too, but Unity allways denied to read the data from my packages.
    How do you get Unity do accept yout UDP-Packages as Data Packages?
     
  8. Jamster

    Jamster

    Joined:
    Apr 28, 2012
    Posts:
    1,102
    Could you not use Pipes? They are, after all, designed for communicating between processes.

    Though I don't know if they're supported on mobile etc.
     
  9. nafasso

    nafasso

    Joined:
    Dec 3, 2013
    Posts:
    22
    hey mistras,

    The script I posted right above your message works perfectly fine for my case of use.
    Actually I did not write the external program so I have no idea how my coworker manage the connection, but what his program does is sending me a string to motify me from an event.
    Thanks to that script I can perfectly receive it and display it in the console or call a function in my Unity program when this string arrives.
    I did not really touch to this code and I suck so much at networking so I am not able to give you a lot of explanations about it.
    Just give it a try. Don't forget to assign the desired socket at the begining of the thread :
    IPEndPoint ipep =new IPEndPoint(IPAddress.Any, 9999); <<<here you should change 9999 with the desired socket to listen to.
     
  10. nebosite

    nebosite

    Joined:
    Mar 13, 2013
    Posts:
    10
    Working with nafasso's nice example, I put this code in my project. I tried to make it clean and easy to follow. This worked like a charm for me.

    -e


    Code (CSharp):
    1.        
    2.  
    3.     public class MyNetworkClass
    4.     {
    5.         public class PacketMessage : MessageBase
    6.         {
    7.             public string messageType;
    8.             public string payload;
    9.         }
    10.  
    11.         /// <summary>
    12.         /// Point this to your own handler to process messages
    13.         /// </summary>
    14.         public Action<PacketMessage> HandleMessage;
    15.  
    16.         private Thread ListenerThread = null;
    17.         private bool KeepListening = true;
    18.  
    19.         public MyNetworkClass()
    20.         {
    21.             HandleMessage = (p) =>
    22.             {
    23.                 Debug.Log("Did not handle message: " + p.messageType);
    24.             };
    25.  
    26.             ListenerThread = new Thread(ListenWorker);
    27.             ListenerThread.Start();
    28.         }
    29.  
    30.         private void ListenWorker()
    31.         {
    32.             KeepListening = true;
    33.             var dataBuffer = new StringBuilder();
    34.             var receiveBuffer = new byte[0x10000]; // Read 64KB at a time
    35.  
    36.             // Set up a local socket for listening
    37.             using (var localSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
    38.             {
    39.                 // Set up an endpoint and start listening
    40.                 var localEndpoint = new IPEndPoint(IPAddress.Any, Port);
    41.                 localSocket.Bind(localEndpoint);
    42.                 localSocket.Listen(10);
    43.                 Debug.Log("Socket Standby....");
    44.  
    45.                 while (KeepListening)
    46.                 {
    47.                     try
    48.                     {
    49.                         // Clear input buffer (Assumption: messages are always string data)
    50.                         dataBuffer.Remove(0, dataBuffer.Length);
    51.  
    52.                         // This call will block until we get a message. Using Async methods
    53.                         // will have better performance, but this is simpler
    54.                         var remoteSocket = localSocket.Accept();
    55.                         Debug.Log("Socket Connected.");
    56.  
    57.                         // Connect to the remote client and receive the message as text
    58.                         var remoteEndpoint = (IPEndPoint)remoteSocket.RemoteEndPoint;
    59.                         var receiveStream = new NetworkStream(remoteSocket);
    60.                         while (receiveStream.Read(receiveBuffer, 0, receiveBuffer.Length) > 0)
    61.                         {
    62.                             var data = Encoding.Default.GetString(receiveBuffer);
    63.                             dataBuffer.Append(data);
    64.                         }
    65.  
    66.                         // Here we assume the remote client is sending us JSON data that describes
    67.                         // a PacketMessage object.  Deserialize the Json and call our custom handler
    68.                         var message = JsonUtility.FromJson<PacketMessage>(dataBuffer.ToString());
    69.                         HandleMessage(message);
    70.                     }
    71.                     catch (Exception e)
    72.                     {
    73.                         // report errors and keep listening.
    74.                         Debug.Log("Network Error: " + e.Message);
    75.  
    76.                         // Sleep 5 seconds so that we don't flood the output with errors
    77.                         Thread.Sleep(5000);
    78.                     }
    79.                 }
    80.             }
    81.         }
    82.     }
    83.  
     
    VResearch likes this.