Re: [gnet] gnet_udp_packet_receive question



On Sunday 05 January 2003 19:51, Axel Bock wrote:

Hi and Happy New Year from me as well :-)


> I have some trouble with this one: from the APIdoc
>
> gnet_udp_packet_receive_new ()
> ... data is a shallow copy and must be deallocated by the caller if
> necessary when appropriate.
>
> what exactly does this mean? *must* be deallocated *if neccessary*? ah.
> makes quite sense :-)
> well, as far as I know is a shallow copy (in this case) a pointer to
> some static memory within the original function, and not some
> malloc()'ed memory. so this doesnt have to be freed, does it?

As far as I understand it, _you_ allocate the buffer 'data', and the function 
gnet_udp_packet_receive_new() just uses this information to make a GUdpPacket 
structure, so in the end it is up to you to free the buffer when you are done 
with the packet that you have received. If you need to free it or not depends 
on whether you allocated the memory dynamically of course.

Here is some code snippet that works for me, maybe you find it helpful (I know 
this is not brilliant code, but it seems to work so far; the code scenario 
here is a client that uses a random UDP socket to send out requests to 
servers and then receives the replies on that same socket. I've left out the 
code where packets are sent).

Cheers
-Tim

PS: List, I hope it's alright to send code snippets. I don't think this one is 
too long, but please feel free to tell me off if this is against list policy 
:-)
_______________________________________________________________________

#include <gnet/gnet.h>
#include <errno.h>

static GUdpSocket	*udp_socket = NULL;


/* udpdoor_parse_packet
 *
 * returns FALSE on error
 *
 */

static gboolean
udpdoor_parse_packet (GUdpPacket *p, guint len)
{
	g_return_val_if_fail (p!=NULL, FALSE);
	g_return_val_if_fail (len>0, FALSE);
	g_return_val_if_fail (p->data!=NULL, FALSE);
	g_return_val_if_fail (p->data[0]==(gint8) SOME_HEADER_BYTE, FALSE);

	if (p->addr)
	{
               /* get sender IP and port from p->addr structure. */
	}

       /* in this case the first byte is a header byte, and the second byte is 
        *  the 'command/request byte'
        */
	switch ((guint8)p->data[1])
	{
		case UDP_PING_SERVER:
		{
                    /* send UDP_PING_SERVER_RETURN .... */
                }
        }
}


/* udpdoor_iochannel_read_watch
 *
 */

static gboolean
udpdoor_iochannel_read_watch (GIOChannel *ioc, GIOCondition condition, 
gpointer data)
{
	GUdpSocket	*udpsock = (GUdpSocket*)data;

	g_return_val_if_fail (udpsock!=NULL, FALSE);

	if (condition&(G_IO_IN|G_IO_PRI))
	{
		guint8		 buf[4096];
		GUdpPacket	*udppack = gnet_udp_packet_receive_new(buf,sizeof(buf));
		gint		 ret;

		memset (buf,0x00,sizeof(buf));
		ret = gnet_udp_socket_receive(udpsock, udppack);
		if (ret>0)
		{
			udpdoor_parse_packet(udppack,ret);
			if (udppack->addr)
			{
				gnet_inetaddr_delete(udppack->addr);
				udppack->addr = NULL;
				gnet_udp_packet_delete(udppack);
			}
		}
	}

	if (condition&G_IO_ERR)
		g_print ("\t**** G_IO_ERR *** - %s\n", g_strerror(errno));
	if (condition&G_IO_HUP)
		g_print ("\t**** G_IO_HUP *** - %s\n", g_strerror(errno));
	if (condition&G_IO_NVAL)
		g_print ("\t**** G_IO_HUP *** - %s\n", g_strerror(errno));

	return TRUE;
}

/* udpdoor_init
 *
 * returns FALSE on error
 *
 */

gboolean
udpdoor_init (void)
{
	udp_socket = gnet_udp_socket_new();

	if (!udp_socket)
		return FALSE;

	(void) g_io_add_watch(gnet_udp_socket_get_iochannel(udp_socket),
	                      G_IO_IN|G_IO_PRI|G_IO_ERR|G_IO_HUP|G_IO_NVAL,
	                      udpdoor_iochannel_read_watch,
	                      (gpointer)udp_socket);

	return TRUE;
}

_______________________________________________________________________




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