Problem with g_io_channel_read_chars



Good day,

I am trying to write app that gonna connect to remote host using TCP
service.

So, I've created connection channel (simple error handling is omitted):

    m_FileDescriptor = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    connect(m_FileDescriptor, (struct sockaddr *)&m_Addr,
sizeof(m_Addr);
    m_pChannel = g_io_channel_unix_new (m_FileDescriptor);

Then set callback:

    Glib::signal_io().connect (SigC::slot(*this,
&TcpClient::tcp_action_cb),
                               m_FileDescriptor, Glib::IO_IN |
Glib::IO_HUP);

...

bool TcpClient::tcp_action_cb (Glib::IOCondition cond)
{
    switch(cond)
    {
    case Glib::IO_IN:
        cout << "tcp_action_cb(): Got Glib::IO_IN"
             << endl;
        if (!tcp_read ())
        {
            // [error handling]
            return false;
        }
        break;
    ...
    }
    return true;
}

Where tcp_read() defined as:

bool TcpClient::tcp_read ()
{
    gsize           rsize;
    gchar           buffer[5120];
    GError         *errcode = 0;
    Glib::ustring   data;
    if ((status = g_io_channel_read_chars ( m_pChannel,
                                            buffer,
                                            sizeof(buffer),
                                           &rsize,
                                           &errcode)) !=
G_IO_STATUS_NORMAL)
    {
        cout << endl << "tcp_read(): " << errcode->message << endl;
        if (errcode) g_free (errcode);
            return false;
        }
    }
    if (errcode) g_free (errcode);

    // [work on buffer data]
    return true;
}

And tcp_write() function:

bool TcpClient::tcp_write (Glib::ustring& str)
{
    GError     *errcode = 0;
    gsize       rsize;

    if (str[str.size()-1] != '\n') str += '\n';

    if (g_io_channel_write_chars (m_pChannel,
                                  str.c_str(),
                                  str.size(),
                                  &rsize,
                                  &errcode) != G_IO_STATUS_NORMAL)
    {
        cout << "tcp_write(): " << errcode->message << endl;
        if (errcode) g_free (errcode);
        return false;
    }
    if (errcode) g_free (errcode);

    // gotta flush chan write buffer to force remote host to get my
message
    // remote host application written in TCL, using socket as well
    // it reads messages and always writes some answer back
    g_io_channel_flush (m_pChannel, 0);

    return true;
}

Ok, the problem is - I am able to read from remote host only once.
connect...

send 1st message, get answer (usually 1-2 text lines "500\n300[n\]") ->
OK.

send 2nd (and any next, if I didn't remove watch callback with error):
then I got error: "Invalid byte sequence in conversion input" that came
in GError.

My TCL app on other side was still running and getting my messages, but
I won't receive any of the answers back.

Could someone explain in what cases that error occurs?
And could someone, please, gimme a hint how to handle reading properly?

thanks
-Andrew





[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]