This script freezes unity. Anyone knows answer?

This networking script freezes unity

using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using UnityEngine;
using UnityEngine.SceneManagement;

public class WebClient : MonoBehaviour
{
    public void Void()
    {
        try
        {
            Debug.Log("faza 1");
            var userString = LoginDataSend("192.168.68.114", "alex.jakubiak@icloud.com", "Alex2008");
            User user = new User();
            if (userString != "false")
            {
                user = JsonUtility.FromJson<User>(userString);
                if (user.isTeacher == true)
                {
                    SceneManager.SetActiveScene(SceneManager.GetSceneByName("Dashboard"));
                }
            }
        }
        catch(Exception e)
        {
            Debug.Log(e);
        }

    }
    public string LoginDataSend(string server, string email, string password)
    {
        try
        {
            // Create a TcpClient.
            // Note, for this client to work you need to have a TcpServer
            // connected to the same address as specified by the server, port
            // combination.
            int port = 2302;
            TcpClient client = new TcpClient(server, port);
            Debug.Log("faza 2");

            var message = "login$" + email + "#" + password;

            // Translate the passed message into ASCII and store it as a Byte array.
            byte[] data = System.Text.Encoding.ASCII.GetBytes(message);
            Debug.Log("faza 3");

            // Get a client stream for reading and writing.
            //  Stream stream = client.GetStream();

            NetworkStream stream = client.GetStream();
            Debug.Log("faza 4");

            // Send the message to the connected TcpServer.
            stream.Write(data, 0, data.Length);
            Debug.Log("faza 5");

            Debug.Log("Sent: "+ email+password);

            // Receive the TcpServer.response.

            // Buffer to store the response bytes.
            data = new byte[512];

            // String to store the response ASCII representation.
            string responseData = string.Empty;

            // Read the first batch of the TcpServer response bytes.
            int bytes = stream.Read(data, 0, data.Length);
            responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes);
            string[] responseArray = responseData.Split('$');
            string responseBool = responseArray[0];
            string responseUser = responseArray[1];
            if (responseBool == "true")
            {
                stream.Close();
                client.Close();
                return responseUser;
            }
            
            // Close everything.
            stream.Close();
            client.Close();
            return "false";
        }
        catch (ArgumentNullException e)
        {
            Debug.Log("ArgumentNullException: " + e);
            return "false";
        }
        catch (SocketException e)
        {
            Debug.Log("SocketException: "+ e);
            return "false";
        }
    }
}

There is try catch everywhere but there aren’t any errors displaying.
Here is server script

using System;
using System.IO;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Text.Json;

class MainServer
{
public static List users = new List();
public static void Main()
{
if (!Directory.Exists(Directory.GetCurrentDirectory() + “/eJournalUsers”))
{
Directory.CreateDirectory(Directory.GetCurrentDirectory() + “/eJournalUsers”);
}
LoadUsers();
TcpListener server = null;
try
{
// Set the TcpListener on port 320.
int port = 2302;
IPAddress localAddr = IPAddress.Parse(“192.168.68.114”);

        // TcpListener server = new TcpListener(port);
        server = new TcpListener(localAddr, port);

        // Start listening for client requests.
        server.Start();

        // Buffer for reading data
        byte[] bytes = new byte[512];
        string data = null;
        string processedData = null;

        // Enter the listening loop.
        while (true)
        {
            Console.Write("Waiting for a connection... ");

            // Perform a blocking call to accept requests.
            // You could also use server.AcceptSocket() here.
            TcpClient client = server.AcceptTcpClient();
            Console.WriteLine("Connected!");

            data = null;

            // Get a stream object for reading and writing
            NetworkStream stream = client.GetStream();

            int i;

            // Loop to receive all the data sent by the client.
            while ((i = stream.Read(bytes, 0, bytes.Length)) != 0)
            {
                // Translate data bytes to a ASCII string.
                data = Encoding.ASCII.GetString(bytes, 0, i);
                Console.WriteLine("Received: {0}", data);
            }

            string[] operationplusdata = data.Split('$');
            string operation = operationplusdata[0];
            data = operationplusdata[1];

            if (operation == "login")
            {
                string[] loginandpassword = data.Split('#');
                var login = loginandpassword[0];
                var password = loginandpassword[1];
                processedData = CheckLoginInformation(login, password);

            }

            byte[] msg = Encoding.ASCII.GetBytes(processedData);

            // Send back a response.
            stream.Write(msg, 0, msg.Length);
            Console.WriteLine("Sent: {0}", processedData);            

        // Shutdown and end connection
        client.Close();
        }
    }
    catch (SocketException e)
    {
        Console.WriteLine("SocketExceptionAtConnecting: {0}", e);
    }
    finally
    {
        // Stop listening for new clients.
        server.Stop();
    }
    Console.WriteLine("

Hit enter to continue…");
Console.Read();
}

static string CheckLoginInformation(string login, string password)
{
    foreach (User user in users)
    {
        if (user.login == login)
        {
            if (user.password == password)
            {
                string jsonString = JsonSerializer.Serialize(user);
                return ("true$" + jsonString);
            }
        }
    }
    return ("false$");
}
public static void AddUser(string fileName, string login, string password, bool isTeacher, string school)
{
    try
    {
        User user = new User();
        user.login = login;
        user.password = password;
        user.isTeacher = isTeacher;
        user.school = school;
        string jsonString = JsonSerializer.Serialize(user);
        string path = Directory.GetCurrentDirectory() + "/eJournalUsers/" + fileName;
        Console.WriteLine(jsonString);
        File.WriteAllText(path, jsonString);
    }
    catch(Exception e)
    {
        Console.WriteLine("Exception wystąpił… {0}", e);
    }
}

static void LoadUsers()
{
    try
    {
        string path = Directory.GetCurrentDirectory() + "/eJournalUsers";
        string[] fileEntries = Directory.GetFiles(path);
        foreach (string fileName in fileEntries)
        {
            Console.WriteLine("File name is: " + fileName);
            string jsonString = File.ReadAllText(fileName);
            User user = JsonSerializer.Deserialize<User>(jsonString);
            users.Add(user);
        }
    }
    catch(Exception e)
    {
        Console.WriteLine(e.ToString());
    }
}

}

[System.Serializable]
class User
{
public string login { get; set; }
public string password { get; set; }
public bool isTeacher { get; set; }
public string school { get; set; }
}

There are no errors. The server is doing what it is supposed to be doing - listening for connections - and until it finds a connection, the application will freeze. It freezes here:

while (true)
{
     Console.Write("Waiting for a connection... ");
     // Perform a blocking call to accept requests.
     // You could also use server.AcceptSocket() here.
     TcpClient client = server.AcceptTcpClient();

    // ...
}

As you can see from the code comments, server.AcceptTcpClient(); perform a blocking call to accept requests. Therefore, the program freezes until it receives a response.


The only way to get around this is to listen for connections asynchronously, or on another thread, which you can do as such:

async void ListenForConnections()
{
      while (true)
      {
           Console.Write("Waiting for a connection... ");
           // Perform a blocking call to accept requests.
           // You could also use server.AcceptSocket() here.
           TcpClient client = new TcpClient();

          // Accepts connection asynchronously so main thread isn't blocked
          await Task.Run(() =>
          {
                client = server.AcceptTcpClient();
          });

          // rest of your code for server goes underneath
 }
}

This is also a C# issue specifically. Not a unity issue. Please explain why you need this in your Unity project or how it is appropriate to this website. @imicz08