从GSocket接收垃圾

时间:2012-02-16 05:39:58

标签: c linux glib

我使用以下函数创建并打开GSocket,然后侦听要在GTK_ENTRY字段中显示的UDP消息。调用open_listen_socket函数,然后我就有一个超时函数,每隔一秒左右调用一次get_incoming_messages函数。

的问题是,当我启动程序,我只得到了一堆乱码表示GTK_ENTRY场了,我的控制台重复错误消息“攀高-警告:无效UTF-8字符串传递给pango_layout_set_text( )“。

我已经能够发送UDP消息没有问题了,但我正在疯狂试图找出接收它们,即使它感觉它应该不那么困难!

感谢您的帮助,以下是我的功能:

static void open_listen_socket()
{

GInetAddress *localAddress;
GSocketAddress *localSocketAddress;


localAddress = g_inet_address_new_from_string("127.0.0.1");
guint16 listenPort = atoi(gtk_entry_get_text (GTK_ENTRY (listenPortField)));

localSocketAddress = g_inet_socket_address_new(localAddress, listenPort);

listenSocket = g_socket_new(G_SOCKET_FAMILY_IPV4, G_SOCKET_TYPE_DATAGRAM, 17, NULL);

g_socket_bind (listenSocket, localSocketAddress, FALSE, NULL);
g_socket_set_blocking(listenSocket, FALSE);
g_socket_listen (listenSocket, NULL);


}

static int get_incoming_message()
{

gchar buffer[1024];

int input_length;

input_length = g_socket_receive(listenSocket, (gchar *)buffer, 1024, NULL, NULL);

gtk_entry_set_text (GTK_ENTRY (current_status_message_box), (const gchar *)buffer);


return 1;

}

另外,如果它有帮助,我不得不添加“返回1”;在get_incoming_message结束时,因为没有它,即使应用程序的其余部分继续工作正常,该进程似乎也卡在该函数内。

/ 以下编辑和更新 * /

好的,使用下面的建议我的工作正常,但是我遇到了一个新问题。看来我对g_socket_receive的调用每次迭代都返回true,如果没有发送消息则打印空行。这意味着我确实看到了我发送的消息,但是它们会在一瞬间从GTK_ENTRY中消失,因为它们在下一次迭代中被空行替换。

static gboolean get_incoming_message()
{

gchar buffer[10] = {0};
GError *err = NULL;

if (g_socket_receive(listenSocket, (gchar *)buffer, 10, NULL, &err) > 0 );
{
    printf("\n%s", buffer);
    gtk_entry_set_text (GTK_ENTRY (current_status_message_box), (const gchar *)buffer);
    return TRUE;
}

return FALSE;

}

我不知道用什么检查来区分实际消息和这些空行!几乎就好像这个套接字在没有发送合法消息的情况下接收到无穷无尽的空数据流。这有意义吗?

/ 搞清楚了! /

我必须添加一个ELSE语句,以便在没有数据时给它做其他事情,以防止它尝试写空行。不确定我明白这一点,所以如果有人有,我会喜欢解释,但我又回来了!再次感谢大家!

2 个答案:

答案 0 :(得分:3)

您的考虑很少:

  1. 每当函数提供使用GError的工具时,请使用它。找出错误消息非常有帮助
  2. 检查函数的返回值,以确保它们已经完成了它们的目的(已经由Joachim指出)
  3. 可用时使用枚举。在这种情况下GSocketProtocol。请勿使用17使用G_SOCKET_PROTOCOL_UDP,因为如果枚举值更改,您的应用程序将会中断
  4. UDP套接字并不真正“监听”,因此g_socket_listen呼叫是多余的
  5. 请根据您发布的内容找到以下示例代码:

    /* gcc -Wall -Wextra `pkg-config --cflags --libs glib-2.0 gio-2.0` gsock.c -o gsock */
    
    #include <glib.h>
    #include <gio/gio.h>
    #include <stdio.h>
    
    #define MAX_RECV 10
    #define TIMEOUT_INTERVAL 1
    
    static GSocket *listenSocket;
    static GMainLoop *loop;
    static gboolean
    recv_msg(gpointer data)
    {
        (void)data;
        static unsigned int count = 0;
        gchar buffer[1024] ={0};
        GError *err = NULL;
    
        if( g_socket_receive(listenSocket, (gchar *)buffer, 1024, NULL, &err) > 0 )
        {
            printf("buff = %s\n", buffer);
        }
        else
        {
            printf(" Nothing posted in last %d sec (Error: %s)\n", TIMEOUT_INTERVAL, err->message);
            g_error_free(err);
        }
    
        if(count++ < MAX_RECV)
            return  TRUE;
    
        /* This is fugly!! :\ */
        g_main_loop_quit(loop);
        return FALSE;
    }
    
    static int
    open_listen_socket(void)
    {
    
        GInetAddress *localAddress;
        GSocketAddress *localSocketAddress;
        GError *err = NULL; /* This is mandatory */
    
        localAddress = g_inet_address_new_from_string("127.0.0.1");
        guint16 listenPort = 31337; /* Can you recongnize this port? xD*/
        localSocketAddress = g_inet_socket_address_new(localAddress, listenPort);
        listenSocket = g_socket_new(G_SOCKET_FAMILY_IPV4, G_SOCKET_TYPE_DATAGRAM, G_SOCKET_PROTOCOL_UDP, &err);
        if( NULL == listenSocket)
        {
            printf("\n Failed to create socket! Error: %s\n", err->message);
            g_error_free(err);
            return -1;
        }
    
        if( FALSE == g_socket_bind (listenSocket, localSocketAddress, FALSE, &err))
        {
            printf("\n Failed to bind! Error: %s\n", err->message);
            g_error_free(err);
            return -1;
        }
        g_socket_set_blocking(listenSocket, FALSE);
        /* UDP socket don't "listen". Uncomment below to see the error message*/
        /*
        if(FALSE == g_socket_listen (listenSocket, &err))
        {
            printf("\n Failed to listen! Error: %s\n", err->message);
            g_error_free(err);
        }
        */
        return 0;
    }
    
    int main(void)
    {
        g_type_init();
        if(open_listen_socket() < 0)
        {
            printf("\n Socket creation went wrong!!\n");
        }
        else
        {
            loop = g_main_loop_new (NULL, TRUE);
            g_timeout_add_seconds(TIMEOUT_INTERVAL, recv_msg, NULL);
            g_main_loop_run(loop);
        }
        return 0;
    }
    

    样品运行:
    终端#1:

    $ ./gsock 
     Nothing posted in last 1 sec (Error: Error receiving data: Resource temporarily unavailable)
     Nothing posted in last 1 sec (Error: Error receiving data: Resource temporarily unavailable)
     Nothing posted in last 1 sec (Error: Error receiving data: Resource temporarily unavailable)
     Nothing posted in last 1 sec (Error: Error receiving data: Resource temporarily unavailable)
     Nothing posted in last 1 sec (Error: Error receiving data: Resource temporarily unavailable)
     Nothing posted in last 1 sec (Error: Error receiving data: Resource temporarily unavailable)
    buff = hello
    
    buff = world
    
     Nothing posted in last 1 sec (Error: Error receiving data: Resource temporarily unavailable)
     Nothing posted in last 1 sec (Error: Error receiving data: Resource temporarily unavailable)
     Nothing posted in last 1 sec (Error: Error receiving data: Resource temporarily unavailable)
    

    2号航站楼:

    $ nc 127.0.0.1 31337 -u
    hello
    world
    ^C
    

    希望这有帮助!

答案 1 :(得分:1)

检查再次接收数据的行...您从哪个插槽读取? 监听套接字!该套接字仅用于接受新连接(通过g_socket_accept)函数。

g_socket_accept返回一个新的套接字(您还必须进行非阻塞),可用于读取和发送。

另外,你应该真正检查g_socket_receive的返回值!在这种情况下,我几乎可以肯定它会返回-1以查找错误,但是您仍然“打印”缓冲区,无论如何都可以包含任何内容。