CTask           *chat_display_task      = NULL;
CTask           *chat_message_task      = NULL;
CTCPSocket      *tcp = TCPSocket(AF_INET);

U0 ChatDisplayTask(I64)
{ // display received messages.
        DocTermNew;
        DocCursor;
        DocPrint(, "$WW,1$");

        while (TaskValidate(chat_message_task))
        {
                Refresh;
        }
}

U0 ChatMessageTask(I64)
{ // take in text.
        U8      *message;

        DocTermNew;
        DocPrint(, "$WW,1$");

        while (message = StrGet("> ",, SGF_SHIFT_ESC_EXIT))
        {
                DocBottom(chat_display_task->put_doc);
                DocPrint(chat_display_task->put_doc,
                                 "$BG,BLUE$$BLACK$<local>$FG$$BG$ %s\n", message);

                TCPSocketSendString(tcp, message);

                DocClear;
                DocPrint(, "$WW,1$");

        }
}

U0 ChatInit()
{
        chat_message_task = Spawn(&ChatMessageTask, NULL, "TCP Chat Message");
        chat_display_task = Spawn(&ChatDisplayTask, NULL, "TCP Chat");
        chat_message_task->win_inhibit = WIG_USER_TASK_DEFAULT;
        chat_display_task->win_inhibit = WIG_USER_TASK_DEFAULT;
        LBts(&chat_message_task->display_flags, DISPLAYf_SHOW);
        LBts(&chat_display_task->display_flags, DISPLAYf_SHOW);

        WinFocus(chat_display_task);
        WinFocus(chat_message_task);

        chat_display_task->win_top              = 2;
        chat_display_task->win_bottom   = TEXT_ROWS / 3;
        chat_display_task->win_left             = TEXT_COLS / 3;
        chat_display_task->win_right    = TEXT_COLS / 3 * 2;

        chat_message_task->win_top              = chat_display_task->win_bottom + 2;
        chat_message_task->win_bottom   = chat_message_task->win_top + 3;
        chat_message_task->win_left             = chat_display_task->win_left;
        chat_message_task->win_right    = chat_display_task->win_right;

}

U0 Chat()
{
        CSocketAddressIPV4       socket_addr;
        CIPV4Address             ip_addr;
        U8                                      *ip_string       = StrGet("Server IPV4: ");
        U8                                      *port_string = StrGet("Server Port: ");
        I64                                      port            = Str2I64(port_string);
        U8                                      *buffer[ETHERNET_FRAME_SIZE];
        I64                                      receive_val;

        while (PresentationToNetwork(AF_INET, ip_string, &ip_addr) == -1)
        {
                "\nERROR: Bad IP entered. Retry.\n";
                ip_string = StrGet("Server IPV4: ");
        }


        Free(ip_string);
        Free(port_string);

        socket_addr.port                        = EndianU16(port);
        socket_addr.family                      = AF_INET;
        socket_addr.address.address     = ip_addr.address;

        tcp->timeout = TCP_TIMEOUT; // use normal timeout for connect()

        "\nConnecting to server...\n";
        if (TCPSocketConnect(tcp, &socket_addr) != 0)
        {
                "\nFailed to connect to server.\n";
                TCPSocketClose(tcp);
                return;
        }
        else
                "\nSuccessfully connected.\n";

        ChatInit;

        tcp->timeout = 0;

        while (TaskValidate(chat_message_task))
        {

                if ((receive_val = TCPSocketReceive(tcp, buffer, ETHERNET_FRAME_SIZE)) != -1)
                {
                        if (receive_val == 0)
                        {
                                "\nServer closed the connection.\n";
                                Kill(chat_message_task);
                                break;
                        }
                        else if (receive_val > 0)
                        {
                                DocBottom(chat_display_task->put_doc);
                                DocPrint(chat_display_task->put_doc,
                                                 "%s\n", buffer);
                                MemSet(buffer, 0, ETHERNET_FRAME_SIZE);
                        }
                }

                Refresh;

        }

        tcp->timeout = TCP_TIMEOUT;

        "\nClosing connected socket...\n";
        if (TCPSocketClose(tcp) == 0)
                "\nSocket closed.\n";
        else
                "\nSocket failed to close.\n";
}

Chat;