使用带有 GTK+ 的 GIOChannel 从发件人处获取 IP 地址
Get IP address from sender using GIOChannel with GTK+
我正在 raspberry pi 上使用 GTK+ 编写 C 程序。
有一个设备通过以太网端口连接到它(所有 UDP 通信)。
该设备向 pi 发送心跳,我可以接收到。
现在我需要将一些东西发送回设备。因此我需要知道它的 IP 地址。
我希望我的程序自动检测消息中的 IP 地址,但我不知道如何获取它。
这是设置套接字的代码:
gd->gXctlServer = G_SOCKET_ADDRESS(g_inet_socket_address_new(g_inet_address_new_any(G_SOCKET_FAMILY_IPV4),XCTLPORT));
gd->gXctlSocket = g_socket_new(G_SOCKET_FAMILY_IPV4,G_SOCKET_TYPE_DATAGRAM,G_SOCKET_PROTOCOL_UDP,&err);
if (gd->gXctlSocket == NULL)
{
g_print("Error creating Xctl socket: %s\n",err->message);
g_assert(err == NULL);
}
if (g_socket_bind(gd->gXctlSocket,gd->gXctlServer,TRUE,&err) == FALSE)
{
g_print("Error binding Xctl socket:%s\n",err->message);
g_assert(err == NULL);
}
// add receiver watch for Xctl messages:
gd->xctlChannel = g_io_channel_unix_new(g_socket_get_fd(gd->gXctlSocket));
// set channel encoding to NULL for binary data:
g_io_channel_set_encoding(gd->xctlChannel,NULL,&err);
if (err != NULL) g_print("error setting encoding: %s\n",err->message);
gd->xctlRrcvEvent = g_io_add_watch(gd->xctlChannel,G_IO_IN,(GIOFunc) xctlreceiver, NULL);
g_io_channel_unref(gd->xctlChannel);
gd是指向一些全局数据的指针,其中server、socket和channel
这是我的监听器的代码:
// this function listens to all Xctl messages
static gboolean xctlreceiver(GIOChannel *channel, GIOCondition condition, gpointer data)
{
char buf[1024];
gsize read;
GError *err = NULL;
g_print("xctlreceiver\n");
if (condition & G_IO_HUP) return FALSE;
g_io_channel_read_chars(channel,buf,sizeof(buf),&read,&err);
if (err != NULL) g_print("error receiving xctl: %s\n",err->message);
g_print("received %d bytes\n",read);
if (isXtouchHeartbeat(buf,read))
{
g_print("received heartbeat from X-touch\n");
}
return TRUE;
}
接收器正在工作,表示收到心跳。
但问题是:如何获取向我发送心跳的设备的 IP 地址。
有人可以帮我吗?
谢谢,
巴特
编辑:解决方案可能比我想象的要简单。
也许我不需要知道发件人的 IP 地址。如果我使用函数 g_io_channel_write_chars 并且使用与 g_io_channel_read_chars 函数相同的通道,它可能会起作用。
我会试试这个,稍后再回来。
我找到了解决问题的方法
我的接收函数现在看起来像这样:
static gboolean xctlreceiver(GIOChannel *channel, GIOCondition condition, gpointer data)
{
char buf[1024];
gsize read;
GError *err = NULL;
g_print("xctlreceiver\n");
GSocketAddress *addr;
if (condition & G_IO_HUP) return FALSE;
if (gd->connectedToController == -1)
{
read = g_socket_receive_from(gd->gXctlSocket,&gd->gXctlController,buf,sizeof(buf),NULL,&err);
g_print("received %d bytes from XCTL socket on address %s\n",read,g_inet_address_to_string(g_inet_socket_address_get_address(G_INET_SOCKET_ADDRESS(gd->gXctlController))));
for (int i=0; i<read; i++)
{
g_print("0x%02X ",buf[i]);
}
g_print("\n");
if (isXtouchHeartbeat(buf,read))
{
g_print("received heartbeat from X-touch\n");
gd->connectedToController = 1;
sendXtouchHeartbeat(NULL);
g_timeout_add_seconds(2,sendXtouchHeartbeat,NULL);
}
}
else
{
g_io_channel_read_chars(channel,buf,sizeof(buf),&read,&err);
if (err != NULL) g_print("error receiving xctl: %s\n",err->message);
g_print("received %d bytes from XCTL channel\n",read);
if (gd->connectedToController == -1)
{
//g_print("X-touch found on ip address: %s\n",inet_ntoa(si_recv.sin_addr));
gd->connectedToController = 1;
}
}
return TRUE;
}
函数g_socket_receive_from在第二个参数中给出了发件人的地址。
我把它放到我的 gd 结构中,以备后用。
希望这对遇到同样问题的人有所帮助。
氪,
巴特
我正在 raspberry pi 上使用 GTK+ 编写 C 程序。 有一个设备通过以太网端口连接到它(所有 UDP 通信)。 该设备向 pi 发送心跳,我可以接收到。 现在我需要将一些东西发送回设备。因此我需要知道它的 IP 地址。 我希望我的程序自动检测消息中的 IP 地址,但我不知道如何获取它。 这是设置套接字的代码:
gd->gXctlServer = G_SOCKET_ADDRESS(g_inet_socket_address_new(g_inet_address_new_any(G_SOCKET_FAMILY_IPV4),XCTLPORT));
gd->gXctlSocket = g_socket_new(G_SOCKET_FAMILY_IPV4,G_SOCKET_TYPE_DATAGRAM,G_SOCKET_PROTOCOL_UDP,&err);
if (gd->gXctlSocket == NULL)
{
g_print("Error creating Xctl socket: %s\n",err->message);
g_assert(err == NULL);
}
if (g_socket_bind(gd->gXctlSocket,gd->gXctlServer,TRUE,&err) == FALSE)
{
g_print("Error binding Xctl socket:%s\n",err->message);
g_assert(err == NULL);
}
// add receiver watch for Xctl messages:
gd->xctlChannel = g_io_channel_unix_new(g_socket_get_fd(gd->gXctlSocket));
// set channel encoding to NULL for binary data:
g_io_channel_set_encoding(gd->xctlChannel,NULL,&err);
if (err != NULL) g_print("error setting encoding: %s\n",err->message);
gd->xctlRrcvEvent = g_io_add_watch(gd->xctlChannel,G_IO_IN,(GIOFunc) xctlreceiver, NULL);
g_io_channel_unref(gd->xctlChannel);
gd是指向一些全局数据的指针,其中server、socket和channel
这是我的监听器的代码:
// this function listens to all Xctl messages
static gboolean xctlreceiver(GIOChannel *channel, GIOCondition condition, gpointer data)
{
char buf[1024];
gsize read;
GError *err = NULL;
g_print("xctlreceiver\n");
if (condition & G_IO_HUP) return FALSE;
g_io_channel_read_chars(channel,buf,sizeof(buf),&read,&err);
if (err != NULL) g_print("error receiving xctl: %s\n",err->message);
g_print("received %d bytes\n",read);
if (isXtouchHeartbeat(buf,read))
{
g_print("received heartbeat from X-touch\n");
}
return TRUE;
}
接收器正在工作,表示收到心跳。
但问题是:如何获取向我发送心跳的设备的 IP 地址。
有人可以帮我吗?
谢谢,
巴特
编辑:解决方案可能比我想象的要简单。
也许我不需要知道发件人的 IP 地址。如果我使用函数 g_io_channel_write_chars 并且使用与 g_io_channel_read_chars 函数相同的通道,它可能会起作用。
我会试试这个,稍后再回来。
我找到了解决问题的方法
我的接收函数现在看起来像这样:
static gboolean xctlreceiver(GIOChannel *channel, GIOCondition condition, gpointer data)
{
char buf[1024];
gsize read;
GError *err = NULL;
g_print("xctlreceiver\n");
GSocketAddress *addr;
if (condition & G_IO_HUP) return FALSE;
if (gd->connectedToController == -1)
{
read = g_socket_receive_from(gd->gXctlSocket,&gd->gXctlController,buf,sizeof(buf),NULL,&err);
g_print("received %d bytes from XCTL socket on address %s\n",read,g_inet_address_to_string(g_inet_socket_address_get_address(G_INET_SOCKET_ADDRESS(gd->gXctlController))));
for (int i=0; i<read; i++)
{
g_print("0x%02X ",buf[i]);
}
g_print("\n");
if (isXtouchHeartbeat(buf,read))
{
g_print("received heartbeat from X-touch\n");
gd->connectedToController = 1;
sendXtouchHeartbeat(NULL);
g_timeout_add_seconds(2,sendXtouchHeartbeat,NULL);
}
}
else
{
g_io_channel_read_chars(channel,buf,sizeof(buf),&read,&err);
if (err != NULL) g_print("error receiving xctl: %s\n",err->message);
g_print("received %d bytes from XCTL channel\n",read);
if (gd->connectedToController == -1)
{
//g_print("X-touch found on ip address: %s\n",inet_ntoa(si_recv.sin_addr));
gd->connectedToController = 1;
}
}
return TRUE;
}
函数g_socket_receive_from在第二个参数中给出了发件人的地址。
我把它放到我的 gd 结构中,以备后用。
希望这对遇到同样问题的人有所帮助。
氪,
巴特