2
votes

This is a follow on from this question

After some more Googling last night I managed to find a nice TCP tutorial I could follow that would allow me to look for connections on an Ip address and port number and display the data that is being sent.

However, I have an issue where my client connects once, I send a message and display it in the debug log but when I stop the application and run it again, Unity freezes. I'm at a loss as to why this happening. Could someone please take a look over this code to see where it might be happening and what I can do to fix it?

I also seem to boot out the connection as soon as I receive a message as well, why is that? The server can re-connect, but I want it to keep the connection once it has it.

public class TCP : MonoBehaviour 
{   
    string ip_address  = "127.0.0.1";
int port = 22;

Thread listen_thread;
TcpListener tcp_listener;
Thread clientThread;
TcpClient tcp_client;
bool isTrue = true;

// Use this for initialization
void Start () 
{
    IPAddress ip_addy = IPAddress.Parse(ip_address);
    tcp_listener = new TcpListener(ip_addy, port);
    listen_thread = new Thread(new ThreadStart(ListenForClients));
    listen_thread.Start();


    Debug.Log("start thread");

}

private void ListenForClients()
{
    this.tcp_listener.Start();

    while(isTrue == true)   
    {
        //blocks until a client has connected to the server
        TcpClient client = this.tcp_listener.AcceptTcpClient();

        //create a thread to handle communication 
        //with connected client
        clientThread = new Thread(new ParameterizedThreadStart(HandleClientComm));
        clientThread.Start(client);


        Debug.Log("Got client " + client);

    }
}

private void HandleClientComm(object client)
{
     tcp_client = (TcpClient)client;
    NetworkStream client_stream = tcp_client.GetStream();


    byte[] message = new byte[4096];
    int bytes_read;

    while(isTrue == true)
    {
        bytes_read = 0;

        try
        {
            //blocks until a client sends a message
            bytes_read = client_stream.Read(message, 0, 4096);
            //Debug.Log(message);

        }
        catch (Exception e)
        {
          //a socket error has occured
          Debug.Log(e.Message);
          break;
        }

        if(bytes_read == 0)
        {
            //client has disconnected
            Debug.Log("Disconnected");
            tcp_client.Close();
            break;
        }

        ASCIIEncoding encoder = new ASCIIEncoding();
        Debug.Log(encoder.GetString(message,0,bytes_read));


    }

    if(isTrue == false)
    {
        tcp_client.Close();
        Debug.Log("closing tcp client");
    }

}

void OnApplicationQuit()
{
    try
    {
        tcp_client.Close();
        isTrue = false;
    }
    catch(Exception e)
    {
        Debug.Log(e.Message);
    }
}

}

Here is a screen shot of my debug log as well to show whats happening: enter image description here

update

updated code that has fixed the kicking of clients. The freeze issue is still persistent when I stop the unity application and re-start it.

further update So after a little further experimenting I have worked out that my project isn't actually freezing. When I start the server (Unity) app the first time everything works fine. But when I close it and try to re run the server, it freezes, until I connect to it with a client. At which point the server works as normal.

So I think I'm not closing the open socket when I close down the server. How can I do that?

1
You close the client, but then go on to read again.Bart Friederichs
Fixed it but I still have the other issue.N0xus
What is causing the first warning in your console? Is it this TCP class? If so, does it ever even reach OnApplicationQuit?Bart

1 Answers

3
votes

You must close the TCP socket that is listening. If you start the application for the first time, the TCP socket will be open. When you stop the application, the TCP socket is still opened and runs in the background.

void OnApplicationQuit()
{
    try
    {
        tcp_client.Close();
        isTrue = false;
    }
    catch(Exception e)
    {
        Debug.Log(e.Message);
    }

    // You must close the tcp listener
    try
    {
        tcp_listener.Stop();
        isTrue = false;
    }
    catch(Exception e)
    {
        Debug.Log(e.Message);
    }
}