Commit d2f5213a authored by Dafydd Harries's avatar Dafydd Harries

add first sketch of UDP abstraction code

darcs-hash:20070108190700-c9803-b7969dc7df8bd91ee759079d0d9e24e06fdc311f.gz
parent df2217fc
AM_CFLAGS = -Wall -Werror $(GLIB_CFLAGS)
libudp_a_SOURCES = udp.h udp.c
noinst_LIBRARIES = libudp.a
noinst_PROGRAMS = udp-client udp-echo-server
udp_client_LDADD = libudp.a $(GLIB_LIBS)
udp_echo_server_LDADD = libudp.a $(GLIB_LIBS)
#include <string.h>
#include <stdio.h>
#include <arpa/inet.h>
#include <glib.h>
#include <udp.h>
gint
main (void)
{
struct UDPSocketManager man;
struct UDPSocket sock;
struct sockaddr_in sin;
udp_socket_manager_init (&man);
if (!man.init (&sock, NULL))
g_assert_not_reached ();
if (inet_pton (AF_INET, "127.0.0.1", &(sin.sin_addr)) < 0)
g_assert_not_reached ();
sin.sin_family = AF_INET;
sin.sin_port = htons (9999);
for (;;)
{
gchar buf[1024];
guint length;
if (fgets (buf, sizeof (buf), stdin) == NULL)
break;
sock.send (&sock, &sin, strlen (buf), buf);
length = sock.recv (&sock, NULL, sizeof (buf), buf);
g_print (buf);
}
return 0;
}
#include <arpa/inet.h>
#include <glib.h>
#include <udp.h>
gint
main (void)
{
struct UDPSocketManager man;
struct UDPSocket sock;
struct sockaddr_in sin;
udp_socket_manager_init (&man);
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = INADDR_ANY;
sin.sin_port = htons (9999);
if (!man.init (&sock, &sin))
g_assert_not_reached ();
for (;;)
{
gchar buf[1024];
guint length;
length = sock.recv (&sock, &sin, sizeof (buf), buf);
#ifdef DEBUG
g_debug ("%s:%d", inet_ntoa (sin.sin_addr), ntohs (sin.sin_port));
#endif
sock.send (&sock, &sin, length, buf);
}
return 0;
}
/*
* convenience API for UDP sockets
*
* easily:
*
* - create sockets and bind them to an interface
* - send and receive packets
* - know who packets are received from
* - select on a number of sockets
*
* also allows faking UDP sockets for testing purposes
*/
#include <arpa/inet.h>
#include <sys/socket.h>
#include <unistd.h>
#include <glib.h>
#include <udp.h>
/*** UDPSocket ***/
static gint
udp_socket_recv (
struct UDPSocket *sock,
struct sockaddr_in *from,
guint len,
gchar *buf)
{
gint recvd;
guint from_len = sizeof (struct sockaddr_in);
recvd = recvfrom (sock->fileno, buf, len, 0,
(struct sockaddr *) from, &from_len);
return recvd;
}
static gboolean
udp_socket_send (
struct UDPSocket *sock,
struct sockaddr_in *to,
guint len,
gchar *buf)
{
sendto (sock->fileno, buf, len, 0, (struct sockaddr *) to,
sizeof (struct sockaddr_in));
return TRUE;
}
static void
udp_socket_close (struct UDPSocket *sock)
{
close (sock->fileno);
}
/*** UDPSocketManager ***/
/* If sin is not NULL, the new socket will be bound to that IP address/port.
* If sin->sin_port is 0, a port will be assigned at random. In all cases, the
* port bound to will be set in sock->port.
*/
static gboolean
udp_socket_manager_init_socket (struct UDPSocket *sock, struct sockaddr_in *sin)
{
gint sockfd;
struct sockaddr_in name;
guint name_len = sizeof (name);
sockfd = socket (PF_INET, SOCK_DGRAM, 0);
if (sock < 0)
return FALSE;
if (sin != NULL)
if (bind (sockfd, (struct sockaddr *) sin, sizeof (*sin)) != 0)
{
close (sockfd);
return FALSE;
}
if (getsockname (sockfd, (struct sockaddr *) &name, &name_len) != 0)
{
close (sockfd);
return FALSE;
}
sock->fileno = sockfd;
sock->port = ntohs (name.sin_port);
sock->send = udp_socket_send;
sock->recv = udp_socket_recv;
sock->close = udp_socket_close;
return TRUE;
}
static void
udp_socket_manager_select (UDPPacketRecvFunc cb)
{
g_assert_not_reached ();
}
void
udp_socket_manager_init (struct UDPSocketManager *man)
{
man->init = udp_socket_manager_init_socket;
man->select = udp_socket_manager_select;
}
void
udp_socket_manager_close (struct UDPSocketManager *man)
{
}
#ifndef _UDP_H
#define _UDP_H
struct UDPSocket
{
guint fileno;
guint port;
gint (*recv) (struct UDPSocket *sock, struct sockaddr_in *from, guint len,
gchar *buf);
gboolean (*send) (struct UDPSocket *sock, struct sockaddr_in *to, guint len,
gchar *buf);
void (*close) (struct UDPSocket *sock);
};
typedef gboolean (*UDPPacketRecvFunc) (struct sockaddr_in *from, guint len,
gchar *buf);
struct UDPSocketManager
{
gboolean (*init) (struct UDPSocket *sock, struct sockaddr_in *sin);
void (*select) (UDPPacketRecvFunc cb);
};
void
udp_socket_manager_init (struct UDPSocketManager *man);
void
udp_socket_manager_deinit (struct UDPSocketManager *man);
#endif /* _UDP_H */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment