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

Json Serialization problems over Async UDP sockets

Discussion in 'Scripting' started by Sioyth96, Jan 16, 2022.

  1. Sioyth96

    Sioyth96

    Joined:
    Feb 19, 2019
    Posts:
    2
    I'm trying to learn Game Networking programming so I started a very simple async udp socket system using Unity, however when I added JSON serialization things got a little bit weird.

    I can connect to the server and send packets with the SendPacket(string msg) method and it will receive it fine on the server side. And it will work fine as long as the size of the msg variable is the same size or bigger. So if I send a string "Hello" and then one "Hello World" will work fine and be able to print it on the other size. However if I was now to send another packet with the string "Hi" nothing would happen and no more connections will work on that socket neither sending new packets.

    I have checked and I'm receiving the packet over the network and it's not empty it has the information however it seems to stop when it gets to the code:

    Packet p = e.Buffer.FromJsonBinary<Packet>();

    Which is on the OnConnect function on my server side.After that function It seems my server stops listening not accepting new connections and no other packets will be receive, I suspect it somehow stops my async process.

    For the Json Serialization I'm using JsonUtility from Unity.

    Any ideas what is happening?

    Server
    Code (CSharp):
    1. public class Server
    2. {
    3.     private static string _protocolID = "hash";
    4.     private static ushort _port = 11000;
    5.     private Socket _socket;
    6.  
    7.     private SocketAsyncEventArgs _event;
    8.     private List<Socket> _connections = new List<Socket>();
    9.    
    10.     public void Start()
    11.     {
    12.         Listen();
    13.     }
    14.  
    15.     private bool Listen()
    16.     {
    17.         // Create UDP Socket
    18.         _socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
    19.  
    20.         // Set the socket into non-blocking mode
    21.         _socket.Blocking = false;
    22.  
    23.         try
    24.         {
    25.             _socket.Bind(new IPEndPoint(IPAddress.Any, _port));
    26.             _event = new SocketAsyncEventArgs();
    27.             _event.Completed += OnConnect;
    28.  
    29.             byte[] buffer = new byte[1024];
    30.             _event.SetBuffer(buffer, 0, 1024);
    31.  
    32.            
    33.             //_socket.ReceiveAsync(_event);
    34.             StartListening(_event);
    35.            
    36.  
    37.         }
    38.         catch (Exception e)
    39.         {
    40.             Debug.LogException(e);
    41.             return false;
    42.         }
    43.  
    44.         return true;
    45.     }
    46.  
    47.     private void StartListening(SocketAsyncEventArgs e)
    48.     {
    49.         //e.AcceptSocket = null;
    50.         _socket.ReceiveAsync(e);
    51.        
    52.     }
    53.     private void OnConnect(object sender, SocketAsyncEventArgs e)
    54.     {
    55.         if (e.BytesTransferred > 0)
    56.         {
    57.             if (e.SocketError != SocketError.Success)
    58.                 Debug.Log("ERROR"); // TODO: Close Socket
    59.  
    60.             Packet p = e.Buffer.FromJsonBinary<Packet>();
    61.             if (p._protocolID != _protocolID)
    62.                 Debug.Log("Protocol Error");
    63.  
    64.             Debug.Log("Connect:" + p._msg);
    65.  
    66.             if (!_socket.ReceiveAsync(e))
    67.             {
    68.                 // Call completed synchonously
    69.                 StartListening(e);
    70.             }
    71.         }
    72.         else
    73.         {
    74.             Debug.Log("No data");
    75.         }
    76.     }
    77. }
    Client
    Code (CSharp):
    1. public class Client
    2. {
    3.     private static string _protocolID = "hash";
    4.     private ushort _port = 11000;
    5.     private string _ip = "127.0.0.1";
    6.     private Socket _socket;
    7.     private SocketAsyncEventArgs _event;
    8.  
    9.     public bool Connect()
    10.     {
    11.  
    12.         // Create UDP Socket
    13.         _socket = new Socket(SocketType.Dgram, ProtocolType.Udp);
    14.  
    15.         // Set the socket into non-blocking mode
    16.         _socket.Blocking = false;
    17.         IPEndPoint ip = new IPEndPoint(IPAddress.Parse(_ip), _port);
    18.  
    19.         _event = new SocketAsyncEventArgs();
    20.         //_event.Completed += Callback;
    21.      
    22.  
    23.         try
    24.         {
    25.             _socket.Connect(ip);
    26.             Debug.Log($"Connection was to {_ip} was sucessfull");
    27.         }
    28.         catch(Exception e)
    29.         {
    30.             Debug.LogException(e);
    31.             Debug.Log("Couldn't connect Socket");
    32.             return false;
    33.         }
    34.  
    35.         return true;
    36.     }
    37.  
    38.     public void SendPacket<T>(T t)
    39.     {
    40.         try
    41.         {
    42.             if (_socket == null)
    43.                 Debug.Log("Null socket");
    44.  
    45.             // Encode the data string into a byte array.
    46.             byte[] buffer = t.ToJsonBinary();
    47.             _event.SetBuffer(buffer, 0, buffer.Length);
    48.  
    49.             // Send the data through the socket.
    50.             //_socket.SendAsync(_event);
    51.  
    52.             bool willRaiseEvent = _socket.SendAsync(_event);
    53.             //if (!willRaiseEvent)
    54.             //{
    55.             //    SendPacket<T>(t);
    56.             //}
    57.         }
    58.         catch (SocketException e)
    59.         {a
    60.             Debug.LogException(e);
    61.             Debug.Log("Couldn't Send Packet");
    62.         }
    63.     }
    64.  
    65.     public void SendPacket(string msg)
    66.     {
    67.         Packet packet = new Packet(_protocolID, msg);
    68.         SendPacket<Packet>(packet);
    69.     }
    70. }
    Json Serialization
    Code (CSharp):
    1.  public static byte[] ToJsonBinary(this object obj)
    2.     {
    3.         return Encoding.ASCII.GetBytes(JsonUtility.ToJson(obj));
    4.     }
    5.  
    6.     public static T FromJsonBinary<T>(this byte[] data)
    7.     {
    8.         return JsonUtility.FromJson<T>(Encoding.ASCII.GetString(data));
    9.     }
    Code (CSharp):
    1. [Serializable]
    2.  
    3. Packet
    4. public struct Packet
    5. {
    6.     public string _protocolID;
    7.     public string _msg;
    8.  
    9.     public Packet(string protocolID, string msg)
    10.     {
    11.         _protocolID = protocolID;
    12.         _msg = msg;
    13.     }
    14. }
     
  2. Sioyth96

    Sioyth96

    Joined:
    Feb 19, 2019
    Posts:
    2
    It seems it's crashing at
    Code (CSharp):
    1. return Encoding.ASCII.GetBytes(JsonUtility.ToJson(obj));
    it throws the exception:

    System.ArgumentException: JSON parse error: The document root must not follow by other values.