- Home /
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("\nHit 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; } }
while(true) is causing or making unity think there is an infinite loop.
Answer by Llama_w_2Ls · May 19, 2021 at 02:01 PM
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
Your answer
Follow this Question
Related Questions
Unity tcp_client only working on localhost 1 Answer
Unity TCP async functions 0 Answers
Problems with TLS handshake 0 Answers
Multiple Cars not working 1 Answer
How do I keep Unity from stopping my Threaded TcpListener.AcceptTcpClient() 0 Answers