Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Simplest code to connect over TCP ip from unity to telnet

Discussion in 'Multiplayer' started by EducaSoft, May 5, 2011.

  1. EducaSoft

    EducaSoft

    Joined:
    Sep 9, 2007
    Posts:
    650
    Hi,

    I'm currently developing a motion capture solution to capture upper body movement using inertial sensors.
    The hardware part can deliver the euler angles data direcly over a tcp/ip connection to any device asking for it on the network, but now I try to make unity connect to it.

    On the wiki I found the following code.

    Code (csharp):
    1. using UnityEngine;
    2.  
    3. using System.Collections;
    4. using System.Net.Sockets;
    5. using System.Net;
    6.  
    7. public class Client : MonoBehaviour {
    8.    
    9.     public string m_IPAdress = "127.0.0.1";
    10.     public const int kPort = 10253;
    11.  
    12.     private static Client singleton;
    13.  
    14.    
    15.     private Socket m_Socket;
    16.     void Awake ()
    17.     {
    18.         m_Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    19.  
    20.         // System.Net.PHostEntry ipHostInfo = Dns.Resolve("host.contoso.com");
    21.         // System.Net.IPAddress remoteIPAddress = ipHostInfo.AddressList[0];
    22.         System.Net.IPAddress    remoteIPAddress  = System.Net.IPAddress.Parse(m_IPAdress);
    23.        
    24.         System.Net.IPEndPoint   remoteEndPoint = new System.Net.IPEndPoint(remoteIPAddress, kPort);
    25.  
    26.         singleton = this;
    27.         m_Socket.Connect(remoteEndPoint);
    28.     }
    29.    
    30.     void OnApplicationQuit ()
    31.     {
    32.         m_Socket.Close();
    33.         m_Socket = null;
    34.     }
    35.    
    36.     static public void Send(MessageData msgData)
    37.     {
    38.         if (singleton.m_Socket == null)
    39.             return;
    40.            
    41.         byte[] sendData = MessageData.ToByteArray(msgData);
    42.         byte[] prefix = new byte[1];
    43.         prefix[0] = (byte)sendData.Length;
    44.         singleton.m_Socket.Send(prefix);
    45.         singleton.m_Socket.Send(sendData);
    46.     }
    47.  
    48.  
    49. }


    Now I see that the send function expects a MessageData object. Does anyone in here know how I could create a SEND function which accepts a simple string variable ?


    And any idea how to check if there is data available from the server and then read it in as a string (or maybe as an array of byte, that doesn't matter too much)?


    Any help/hints would be highly appreciated since this is a very simple connection but I need to make it very robust because it will need to send quite some data from the hardware to unity.


    Kind regards,

    Bart
     
  2. appels

    appels

    Joined:
    Jun 25, 2010
    Posts:
    2,687
    untested but this should work i think :

    Code (csharp):
    1.     static public void Send(string msgData)
    2.     {
    3.         if (singleton.m_Socket == null)
    4.             return;
    5.  
    6.     System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
    7.         byte[] sendData = encoding.GetBytes(msgData);
    8.         byte[] prefix = new byte[1];
    9.         prefix[0] = (byte)sendData.Length;
    10.         singleton.m_Socket.Send(prefix);
    11.         singleton.m_Socket.Send(sendData);
    12.     }
    if it doesn't work you should have a look on microsoft's site on sockets in .net 2.0
    http://msdn.microsoft.com/en-us/library/system.net.sockets.socket.aspx#Y6100
     
    Last edited: May 5, 2011
  3. EducaSoft

    EducaSoft

    Joined:
    Sep 9, 2007
    Posts:
    650
    Thank you.

    Would you also have an idea how I can read data from my connection?

    In flash we do this by ataching an event handler in code, but I suppose in unity this is not the way to do it and I'll have to POLL for incoming data in every Update() cycle? Any hints on that?

    Kind regards,

    Bart
     
  4. appels

    appels

    Joined:
    Jun 25, 2010
    Posts:
    2,687
    yes, you would do something like this in the update function :

    Code (csharp):
    1. bytes = s.Receive(bytesReceived, bytesReceived.Length, 0);
    s refers to the socket
    and then decode the bytes to a string
     
  5. EducaSoft

    EducaSoft

    Joined:
    Sep 9, 2007
    Posts:
    650
    so bytesReceived would contain the bytes received. What data type would this bytesReceived be?

    And bytesReceived.Length is the amount of bytes received, but it this a value which I have to enter somewhere or is it done in such a way that when I call this Receive method on my socket, the bytesReceived.length is auto-filled?

    I found in the .net docs that there a quite a lot of overloaded Receive methods available
     
  6. appels

    appels

    Joined:
    Jun 25, 2010
    Posts:
    2,687
    the data is of type byte[]
    then decode like this :

    Code (csharp):
    1. System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
    2. string sendData = encoding.GetString(bytesReceived);
     
  7. EducaSoft

    EducaSoft

    Joined:
    Sep 9, 2007
    Posts:
    650
    Hmmm, still troubles.

    I tried the code below


    Now I'm 100% sure that my unity program does connect to port 5333 on localhost and that server listening on port 5333 does send data to unity.

    However, I thought that I would see information received in the GUIlabel, but it shows absolutely nothing.

    Anyone have an idea what I do wrong?


    Kind regards,

    Bart
     
  8. appels

    appels

    Joined:
    Jun 25, 2010
    Posts:
    2,687
    yeah that won't work.

    Code (csharp):
    1. void Update () {
    2. bytes = m_Socket.Receive(bytesReceived, bytesReceived.Length, 0);  
    3. System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
    4. sendData = encoding.GetString(bytesReceived);  
    5. }
    it should be in the lines of :

    Code (csharp):
    1. void Update () {
    2. bytes = m_Socket.Receive(bytesReceived, bytesReceived.Length, 0);  
    3. while(bytes != null)
    4. {
    5.     System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
    6.     string receivedData = encoding.GetString(bytes);
    7. }
    8. }
    then your receivedData is your received text
     
  9. EducaSoft

    EducaSoft

    Joined:
    Sep 9, 2007
    Posts:
    650
    The problem persists.

    My latest version of the code is now

    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using System.Net.Sockets;
    5. using System.Net;
    6.  
    7.  
    8. public class Client : MonoBehaviour {
    9.    
    10.     public string m_IPAdress = "127.0.0.1";
    11.     public const int kPort = 5333;
    12.     public int bytes;
    13.     private Socket m_Socket;
    14.     public byte[] bytesReceived;
    15.     public string receivedData="";
    16.  
    17.     void Awake(){
    18.         m_Socket=new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
    19.         System.Net.IPAddress    remoteIPAddress  = System.Net.IPAddress.Parse(m_IPAdress);
    20.         System.Net.IPEndPoint   remoteEndPoint = new System.Net.IPEndPoint(remoteIPAddress, kPort);
    21.         m_Socket.Connect(remoteEndPoint);
    22.     }
    23.    
    24.     void Update () {
    25.         bytes = m_Socket.Receive(bytesReceived, bytesReceived.Length, 0);
    26.         while(bytes != 0)
    27.         {
    28.             System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
    29.             string receivedData = encoding.GetString(bytesReceived);
    30.         }
    31.     }  
    32.    
    33.         void OnApplicationQuit ()
    34.     {
    35.         m_Socket.Close();
    36.         m_Socket = null;
    37.     }
    38.    
    39.     void OnGUI() {
    40.      GUI.Label(new Rect(0, 40, 1000, 400), receivedData);
    41. }
    42. }

    And somehow it doesn't receive data.
    If I look at the value of variable bytes, then its always 0, so maybe something is still terribly wrong in my code?

    The tcp server does show that my client program connected and the server is absolutely surely sending data.


    Any idea what could be wrong here?



    By the way, I had to change 1 line to
    Code (csharp):
    1. while(bytes != 0)
    because if I used
    Code (csharp):
    1. while(bytes != null)
    then unity goes into infinite loop and hangs.
     
  10. appels

    appels

    Joined:
    Jun 25, 2010
    Posts:
    2,687
    sent you a pm
     
  11. holyjewsus

    holyjewsus

    Joined:
    Mar 7, 2011
    Posts:
    624
    Hey, I'm also using an arduino to send data, I can't use serial as I'm on mac and mono shoots errors, but I was hoping I can send data from the arduino with ethernet shield in the meantime. Did you ever get this working? I would really appreciate the help.
     
  12. ciaravoh

    ciaravoh

    Joined:
    Dec 16, 2009
    Posts:
    252
    @educasoft,

    you should not use blocking communication. The best way is to use threading (System.Threading) and callback to ensure you will read/write to the TCP buffer without blocking your Unity application.
     
  13. EducaSoft

    EducaSoft

    Joined:
    Sep 9, 2007
    Posts:
    650
    I currently am not working on this, but here is the script which worked. There is too much code in that script but you can isolate the networking specific stuff I guess

    Code (csharp):
    1.  
    2. using UnityEngine;
    3.  
    4. using System.Collections;
    5.  
    6. using System;
    7.  
    8. using System.IO;
    9.  
    10. using System.Net.Sockets;
    11.  
    12. //using System.Globalization.NumberStyles;
    13.  
    14.  
    15.  
    16. public class Sockesfleximan : MonoBehaviour
    17.  
    18. {
    19.  
    20.     public string tekst;
    21.  
    22.     public float rotatieX;
    23.  
    24.     public float rotatieY;
    25.  
    26.     public float rotatieZ;
    27.  
    28.     public Transform nek;
    29.  
    30.    
    31.  
    32.    
    33.  
    34.     public byte[] bytesX = new byte[4];
    35.  
    36.     public byte[] bytesY = new byte[4];
    37.  
    38.     public byte[] bytesZ = new byte[4];
    39.  
    40.     public byte[] bytesW = new byte[4];
    41.  
    42.    
    43.  
    44.     public float xValue= (float)0.0;
    45.  
    46.     public float yValue= (float)0.0;
    47.  
    48.     public float zValue= (float)0.0;
    49.  
    50.  
    51.  
    52.    
    53.  
    54.     public Quaternion rot=Quaternion.identity;
    55.  
    56.     public Quaternion sensor=Quaternion.identity;
    57.  
    58.  
    59.  
    60.    
    61.  
    62.     public float[] qq = new float[4];
    63.  
    64.    
    65.  
    66.     internal Boolean socketReady = false;
    67.  
    68.     TcpClient mySocket;
    69.  
    70.     NetworkStream theStream;
    71.  
    72.     StreamWriter theWriter;
    73.  
    74.     StreamReader theReader;
    75.  
    76.     String Host = "localhost";
    77.  
    78.     Int32 Port = 5333;
    79.  
    80.    
    81.  
    82.     void Update()
    83.  
    84.     {
    85.  
    86.        string receivedText = readSocket();
    87.  
    88.         if (receivedText != "")
    89.  
    90.         {
    91.  
    92.         tekst=receivedText;
    93.  
    94.            
    95.  
    96.         bytesX[0]=(byte)(HexToByte(tekst.Substring(0,1))*16+HexToByte(tekst.Substring(1,1)));
    97.  
    98.         bytesX[1]=(byte)(HexToByte(tekst.Substring(2,1))*16+HexToByte(tekst.Substring(3,1)));
    99.  
    100.         bytesX[2]=(byte)(HexToByte(tekst.Substring(4,1))*16+HexToByte(tekst.Substring(5,1)));
    101.  
    102.         bytesX[3]=(byte)(HexToByte(tekst.Substring(6,1))*16+HexToByte(tekst.Substring(7,1)));
    103.  
    104.         bytesY[0]=(byte)(HexToByte(tekst.Substring(8,1))*16+HexToByte(tekst.Substring(9,1)));
    105.  
    106.         bytesY[1]=(byte)(HexToByte(tekst.Substring(10,1))*16+HexToByte(tekst.Substring(11,1)));
    107.  
    108.         bytesY[2]=(byte)(HexToByte(tekst.Substring(12,1))*16+HexToByte(tekst.Substring(13,1)));
    109.  
    110.         bytesY[3]=(byte)(HexToByte(tekst.Substring(14,1))*16+HexToByte(tekst.Substring(15,1)));
    111.  
    112.         bytesZ[0]=(byte)(HexToByte(tekst.Substring(16,1))*16+HexToByte(tekst.Substring(17,1)));
    113.  
    114.         bytesZ[1]=(byte)(HexToByte(tekst.Substring(18,1))*16+HexToByte(tekst.Substring(19,1)));
    115.  
    116.         bytesZ[2]=(byte)(HexToByte(tekst.Substring(20,1))*16+HexToByte(tekst.Substring(21,1)));
    117.  
    118.         bytesZ[3]=(byte)(HexToByte(tekst.Substring(22,1))*16+HexToByte(tekst.Substring(23,1)));
    119.  
    120.         bytesW[0]=(byte)(HexToByte(tekst.Substring(24,1))*16+HexToByte(tekst.Substring(25,1)));
    121.  
    122.         bytesW[1]=(byte)(HexToByte(tekst.Substring(26,1))*16+HexToByte(tekst.Substring(27,1)));
    123.  
    124.         bytesW[2]=(byte)(HexToByte(tekst.Substring(28,1))*16+HexToByte(tekst.Substring(29,1)));
    125.  
    126.         bytesW[3]=(byte)(HexToByte(tekst.Substring(30,1))*16+HexToByte(tekst.Substring(31,1)));
    127.  
    128.            
    129.  
    130.         sensor.x=System.BitConverter.ToSingle( bytesX, 0); 
    131.  
    132.         sensor.y=System.BitConverter.ToSingle( bytesY, 0); 
    133.  
    134.         sensor.z=System.BitConverter.ToSingle( bytesZ, 0); 
    135.  
    136.         sensor.w=System.BitConverter.ToSingle( bytesW, 0); 
    137.  
    138.  
    139.  
    140.         qq[0]=System.BitConverter.ToSingle( bytesX, 0);
    141.  
    142.         qq[1]=System.BitConverter.ToSingle( bytesY, 0);
    143.  
    144.         qq[2]=System.BitConverter.ToSingle( bytesZ, 0);
    145.  
    146.         qq[3]=System.BitConverter.ToSingle( bytesW, 0);
    147.  
    148.  
    149.  
    150.         rotatieX=sensor.eulerAngles.x;
    151.  
    152.         rotatieY=sensor.eulerAngles.y;
    153.  
    154.         rotatieZ=sensor.eulerAngles.z;
    155.  
    156.            
    157.  
    158.            
    159.  
    160.            
    161.  
    162. //      rot.x=sensor.x;
    163.  
    164. //      rot.y=sensor.y;
    165.  
    166. //      rot.z=sensor.z;
    167.  
    168. //      rot.w=sensor.w;
    169.  
    170.            
    171.  
    172.         rot.x=-qq[1];
    173.  
    174.         rot.y=qq[0];
    175.  
    176.         rot.z=-qq[2];
    177.  
    178.         rot.w=qq[3];
    179.  
    180.            
    181.  
    182.         rot *= Quaternion.Euler(Vector3.up * yValue);
    183.  
    184.         rot *= Quaternion.Euler(Vector3.right * xValue);
    185.  
    186.         rot *= Quaternion.Euler(Vector3.forward * zValue);
    187.  
    188.            
    189.  
    190.            
    191.  
    192.            
    193.  
    194.     //rot *= Quaternion.Euler(Vector3(90,90,90));
    195.  
    196.            
    197.  
    198.            
    199.  
    200.         nek.rotation=rot;
    201.  
    202.         //nek.rotation=Quaternion.Euler(-rotatieY,rotatieX,-rotatieZ);
    203.  
    204.         }
    205.  
    206.     }
    207.  
    208.  
    209.  
    210.     void OnGUI()
    211.  
    212.     {
    213.  
    214.        
    215.  
    216.         if (!socketReady)
    217.  
    218.         {  
    219.  
    220.          if (GUILayout.Button("Connect"))
    221.  
    222.          {
    223.  
    224.              setupSocket();
    225.  
    226.              writeSocket("serverStatus:");
    227.  
    228.          }
    229.  
    230.         }
    231.  
    232.  
    233.  
    234.        // if (GUILayout.Button("Send"))
    235.  
    236.        // {
    237.  
    238.        //     writeSocket("test string");
    239.  
    240.        // }
    241.  
    242.  
    243.  
    244.        // if (GUILayout.Button("Close"))
    245.  
    246.        // {
    247.  
    248.        //     closeSocket();
    249.  
    250.        // }
    251.  
    252.        
    253.  
    254.         //GUI.Label(new Rect(0, 40, 1000, 400), tekst);
    255.  
    256.         if (socketReady)
    257.  
    258.         {  
    259.  
    260.          xValue = GUI.HorizontalSlider (new Rect (25, 25, 360, 30), (float)xValue, 180.0f, -180.0f);
    261.  
    262.          yValue = GUI.HorizontalSlider (new Rect (25, 50, 360, 30), (float)yValue, 180.0f, -180.0f);
    263.  
    264.          zValue = GUI.HorizontalSlider (new Rect (25, 75, 360, 30), (float)zValue, 180.0f, -180.0f);
    265.  
    266.         }
    267.  
    268.        
    269.  
    270.     }
    271.  
    272.  
    273.  
    274.     void OnApplicationQuit()
    275.  
    276.     {
    277.  
    278.         closeSocket();
    279.  
    280.     }
    281.  
    282.  
    283.  
    284.     public void setupSocket()
    285.  
    286.     {
    287.  
    288.         try
    289.  
    290.         {
    291.  
    292.             mySocket = new TcpClient(Host, Port);
    293.  
    294.             theStream = mySocket.GetStream();
    295.  
    296.             theWriter = new StreamWriter(theStream);
    297.  
    298.             theReader = new StreamReader(theStream);
    299.  
    300.             socketReady = true;
    301.  
    302.         }
    303.  
    304.  
    305.  
    306.         catch (Exception e)
    307.  
    308.         {
    309.  
    310.             Debug.Log("Socket error: " + e);
    311.  
    312.         }
    313.  
    314.     }
    315.  
    316.  
    317.  
    318.     public void writeSocket(string theLine)
    319.  
    320.     {
    321.  
    322.         if (!socketReady)
    323.  
    324.             return;
    325.  
    326.         String foo = theLine + "\r\n";
    327.  
    328.         theWriter.Write(foo);
    329.  
    330.         theWriter.Flush();
    331.  
    332.     }
    333.  
    334.  
    335.  
    336.     public String readSocket()
    337.  
    338.     {
    339.  
    340.         if (!socketReady)
    341.  
    342.             return "";
    343.  
    344.         if (theStream.DataAvailable)
    345.  
    346.             return theReader.ReadLine();
    347.  
    348.             //return theReader.ReadToEnd();
    349.  
    350.         return "";
    351.  
    352.     }
    353.  
    354.  
    355.  
    356.     public void closeSocket()
    357.  
    358.     {
    359.  
    360.         if (!socketReady)
    361.  
    362.             return;
    363.  
    364.         theWriter.Close();
    365.  
    366.         theReader.Close();
    367.  
    368.         mySocket.Close();
    369.  
    370.         socketReady = false;
    371.  
    372.     }
    373.  
    374.  
    375.  
    376.     private byte HexToByte(string hexVal)
    377.  
    378.     {
    379.  
    380.         if (hexVal=="0") return (0);
    381.  
    382.         else if (hexVal=="1") return (1);
    383.  
    384.         else if (hexVal=="2") return (2);
    385.  
    386.         else if (hexVal=="3") return (3);
    387.  
    388.         else if (hexVal=="4") return (4);
    389.  
    390.         else if (hexVal=="5") return (5);
    391.  
    392.         else if (hexVal=="6") return (6);
    393.  
    394.         else if (hexVal=="7") return (7);
    395.  
    396.         else if (hexVal=="8") return (8);
    397.  
    398.         else if (hexVal=="9") return (9);
    399.  
    400.         else if (hexVal=="A") return (10);
    401.  
    402.         else if (hexVal=="B") return (11);
    403.  
    404.         else if (hexVal=="C") return (12);
    405.  
    406.         else if (hexVal=="D") return (13);
    407.  
    408.         else if (hexVal=="E") return (14);
    409.  
    410.         else if (hexVal=="F") return (15);
    411.  
    412.         else return (0);
    413.  
    414.     }
    415.  
    416. }
    417.  
     
    Last edited: Sep 11, 2011
  14. bigkahuna

    bigkahuna

    Joined:
    Apr 30, 2006
    Posts:
    5,434
    Could you add the
    Code (csharp):
    1.  brackets please?  ;)
     
  15. EducaSoft

    EducaSoft

    Joined:
    Sep 9, 2007
    Posts:
    650
    Of course, didn't notice I hadn't done it :)
     
  16. bigkahuna

    bigkahuna

    Joined:
    Apr 30, 2006
    Posts:
    5,434
    Thanks! :)
     
  17. Darren Wong

    Darren Wong

    Joined:
    Nov 14, 2012
    Posts:
    4
    how can i change the int32 port into String?
    cause i need to make it user input for the port.
    thank you
     
  18. appels

    appels

    Joined:
    Jun 25, 2010
    Posts:
    2,687
  19. eskimojoe

    eskimojoe

    Joined:
    Jun 4, 2012
    Posts:
    1,440