Получение мусора от GSocket - PullRequest
       0

Получение мусора от GSocket

0 голосов
/ 16 февраля 2012

Я использую следующие функции для создания и открытия GSocket, а затем прослушиваю сообщения UDP для отображения в поле GTK_ENTRY. Вызывается функция open_listen_socket, а затем по истечении времени ожидания у меня есть функция, вызывающая функцию get_incoming_messages каждую секунду или около того.

Проблема в том, что при запуске программы в поле GTK_ENTRY появляется только куча мусорных символов, и моя консоль повторяет сообщение об ошибке "Pango-WARNING: неверная строка 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;

}

Кроме того, если это вообще поможет, мне пришлось добавить «return 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 ]

3 голосов
/ 16 февраля 2012

Есть несколько указателей для вашего рассмотрения:

  1. Всякий раз, когда функция предоставляет возможность использовать GError, пожалуйста, используйте ее. Очень полезно узнать сообщение об ошибке
  2. Проверьте возвращаемое значение функций, чтобы убедиться, что они выполнили то, для чего предназначались (уже указано Иоахимом)
  3. Используйте enum, когда доступно. В этом случае GSocketProtocol. Не используйте 17, вместо этого используйте G_SOCKET_PROTOCOL_UDP, так как ваше приложение прервется, если значение enum изменится
  4. UDP-сокеты на самом деле не "слушают", поэтому g_socket_listen вызов избыточен

Ниже приведен пример кода на основе того, что вы разместили в вашем распоряжении:

/* 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 голос
/ 16 февраля 2012

Проверьте строку, где вы получаете данные снова ... Из какого сокета вы читаете? слушающая розетка!Этот сокет используется только для приема новых подключений (через функцию g_socket_accept).

g_socket_accept возвращает новый сокет (который вы также должны сделать неблокирующим), чтоможет использоваться для чтения и отправки.

Кроме того, вы действительно должны проверить возвращаемое значение из g_socket_receive!В этом случае я почти могу поспорить, что он возвращает -1 за ошибку, но вы все равно «печатаете» буфер, который может содержать что угодно.

...