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.
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
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: Initialize the Network Transport Layer Configure network topology Create Host Start communication (handling connections and sending/receiving messages) 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.
Hey, yes I will run some tests to figure out how to set it for my project. In addition, I found this article that I think is clearer than the Unity Doc : http://www.robotmonkeybrain.com/good-enough-guide-to-unitys-unet-transport-layer-llapi/
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): using UnityEngine; using System; using System.Collections; using System.Net.Sockets; using System.Threading; using System.Net; using System.Collections.Generic; using System.Text; public class Server : MonoBehaviour { Socket SeverSocket = null; Thread Socket_Thread = null; bool Socket_Thread_Flag = false; //for received message // private float mouse_delta_x; // private float mouse_delta_y; // private bool isTapped; // private bool isDoubleTapped; // // public float getMouseDeltaX(){return mouse_delta_x; } // public float getMouseDeltaY(){return mouse_delta_y; } // public bool getTapped(){return isTapped;} // public bool getDoubleTapped(){return isDoubleTapped;} // // public void setMouseDeltaX(float dx){mouse_delta_x = dx;} // public void setMouseDeltaY(float dy){mouse_delta_y = dy;} // public void setTapped(bool t){isTapped = t;} // public void setDoubleTapped(bool t){isDoubleTapped = t;} // // private int tick =0; //private string[] receivedMSG; //public string[] getMsg(){return receivedMSG; } string[] stringSeparators = new string[] {"*TOUCHEND*","*MOUSEDELTA*","*Tapped*","*DoubleTapped*"}; void Awake() { Socket_Thread = new Thread(Dowrk); Socket_Thread_Flag = true; Socket_Thread.Start(); } private void Dowrk() { //receivedMSG = new string[10]; SeverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); IPEndPoint ipep = new IPEndPoint(IPAddress.Any, 9999); SeverSocket.Bind(ipep); SeverSocket.Listen(10); Debug.Log("Socket Standby...."); Socket client = SeverSocket.Accept();//client에서 수신을 요청하면 접속합니다. Debug.Log("Socket Connected."); IPEndPoint clientep = (IPEndPoint)client.RemoteEndPoint; NetworkStream recvStm = new NetworkStream(client); //tick = 0; while (Socket_Thread_Flag) { byte[] receiveBuffer = new byte[1024 * 80]; try { //print (recvStm.Read(receiveBuffer, 0, receiveBuffer.Length)); if(recvStm.Read(receiveBuffer, 0, receiveBuffer.Length) == 0 ){ // when disconnected , wait for new connection. client.Close(); SeverSocket.Close(); SeverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); ipep = new IPEndPoint(IPAddress.Any, 10000); SeverSocket.Bind(ipep); SeverSocket.Listen(10); Debug.Log("Socket Standby...."); client = SeverSocket.Accept();//client에서 수신을 요청하면 접속합니다. Debug.Log("Socket Connected."); clientep = (IPEndPoint)client.RemoteEndPoint; recvStm = new NetworkStream(client); }else{ string Test = Encoding.Default.GetString(receiveBuffer); //string Test = Convert.ToBase64String(receiveBuffer); //Test = Test.Normalize(); print (Test); //string[] splitMsg = Test.Split(stringSeparators,System.StringSplitOptions.RemoveEmptyEntries); // parsing gogo // string[] splitMsg = Test.Split('*'); //// print (splitMsg); // if(splitMsg.Length>1) // { // if(splitMsg[1].CompareTo("Tapped")==0){ // print ("tap"); // isTapped = true; // }else if(splitMsg[1].CompareTo("DoubleTapped")==0){ // print ("double tap"); // isDoubleTapped = true; // }else if(splitMsg[1].CompareTo("MOUSEDELTA")==0){ // print ("move"); // //string[] lastMsg = splitMsg[splitMsg.Length-1].Split('*'); // mouse_delta_x = (float)Convert.ToDouble(splitMsg[2]); // mouse_delta_y = (float)Convert.ToDouble(splitMsg[3]); // }else{ // print ("F*** :"+splitMsg[1].Length); // // } // } // // string singletap = "one"; // string doubletap = "two"; // if(splitMsg.Length>0){ // // // // if(lastMsg.Length>1){ // // // }else{ // // print ("split msg : "+splitMsg[0]); // int tmp = (int)Convert.ToInt32(splitMsg[0]); // if(tmp ==1){ // // print ("Tapped!~"); // // isTapped = true; // // }else if(tmp ==2){ // // print ("Double Tapped!~"); // // isDoubleTapped = true; // // }else{ // // } // } // }else{ // // } //print (receivedMSG); } } catch (Exception e) { Socket_Thread_Flag = false; client.Close(); SeverSocket.Close(); continue; } } } void OnApplicationQuit() { try { Socket_Thread_Flag = false; Socket_Thread.Abort(); SeverSocket.Close(); Debug.Log("Bye~~"); } catch { Debug.Log("Error when finished..."); } } }
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?
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.
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.
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): public class MyNetworkClass { public class PacketMessage : MessageBase { public string messageType; public string payload; } /// <summary> /// Point this to your own handler to process messages /// </summary> public Action<PacketMessage> HandleMessage; private Thread ListenerThread = null; private bool KeepListening = true; public MyNetworkClass() { HandleMessage = (p) => { Debug.Log("Did not handle message: " + p.messageType); }; ListenerThread = new Thread(ListenWorker); ListenerThread.Start(); } private void ListenWorker() { KeepListening = true; var dataBuffer = new StringBuilder(); var receiveBuffer = new byte[0x10000]; // Read 64KB at a time // Set up a local socket for listening using (var localSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) { // Set up an endpoint and start listening var localEndpoint = new IPEndPoint(IPAddress.Any, Port); localSocket.Bind(localEndpoint); localSocket.Listen(10); Debug.Log("Socket Standby...."); while (KeepListening) { try { // Clear input buffer (Assumption: messages are always string data) dataBuffer.Remove(0, dataBuffer.Length); // This call will block until we get a message. Using Async methods // will have better performance, but this is simpler var remoteSocket = localSocket.Accept(); Debug.Log("Socket Connected."); // Connect to the remote client and receive the message as text var remoteEndpoint = (IPEndPoint)remoteSocket.RemoteEndPoint; var receiveStream = new NetworkStream(remoteSocket); while (receiveStream.Read(receiveBuffer, 0, receiveBuffer.Length) > 0) { var data = Encoding.Default.GetString(receiveBuffer); dataBuffer.Append(data); } // Here we assume the remote client is sending us JSON data that describes // a PacketMessage object. Deserialize the Json and call our custom handler var message = JsonUtility.FromJson<PacketMessage>(dataBuffer.ToString()); HandleMessage(message); } catch (Exception e) { // report errors and keep listening. Debug.Log("Network Error: " + e.Message); // Sleep 5 seconds so that we don't flood the output with errors Thread.Sleep(5000); } } } } }