diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/udpreceive-help.pd | 90 | ||||
-rw-r--r-- | net/udpreceive.c | 103 |
2 files changed, 113 insertions, 80 deletions
diff --git a/net/udpreceive-help.pd b/net/udpreceive-help.pd index 530e503..5bded46 100644 --- a/net/udpreceive-help.pd +++ b/net/udpreceive-help.pd @@ -1,43 +1,47 @@ -#N canvas 238 505 742 371 12;
-#X floatatom 394 264 3 0 0 0 - - -;
-#X floatatom 421 264 3 0 0 0 - - -;
-#X floatatom 448 264 3 0 0 0 - - -;
-#X floatatom 475 264 3 0 0 0 - - -;
-#X obj 171 120 udpreceive 9997;
-#X floatatom 502 265 5 0 0 0 - - -;
-#X obj 394 238 unpack 0 0 0 0 0;
-#X msg 171 90 status;
-#X floatatom 273 185 9 0 0 0 - - -;
-#X obj 454 211 tgl 15 0 empty empty empty 17 7 0 10 -4034 -1 -1 0 1
-;
-#X floatatom 333 211 9 0 0 0 - - -;
-#X text -30 90 get status on right outlet:;
-#X text 166 185 bytes received:;
-#X text 181 209 total bytes received:;
-#X text 351 263 from:;
-#X text 299 97 Specify a multicast address (from 224.0.0.0 to 239.255.255.255)
-to use multicasting;
-#X text 162 57 Creation arguments: port number to listen on (required)
-;
-#X text 124 33 [udpreceive] receives bytes over a udp connection.;
-#X obj 171 254 spigot;
-#X obj 210 234 tgl 15 0 empty empty enable_print: -77 8 0 10 -4034
--1 -1 0 1;
-#X obj 171 279 print received;
-#X obj 273 152 route received total from multicast;
-#X text 301 75 IP address to listen on (optional);
-#X text 466 320 Martin Peach 2010/08/05;
-#X connect 4 0 18 0;
-#X connect 4 1 21 0;
-#X connect 6 0 0 0;
-#X connect 6 1 1 0;
-#X connect 6 2 2 0;
-#X connect 6 3 3 0;
-#X connect 6 4 5 0;
-#X connect 7 0 4 0;
-#X connect 18 0 20 0;
-#X connect 19 0 18 1;
-#X connect 21 0 8 0;
-#X connect 21 1 10 0;
-#X connect 21 2 6 0;
-#X connect 21 3 9 0;
+#N canvas 238 314 742 409 12; +#X floatatom 414 304 3 0 0 0 - - -; +#X floatatom 441 304 3 0 0 0 - - -; +#X floatatom 468 304 3 0 0 0 - - -; +#X floatatom 495 304 3 0 0 0 - - -; +#X obj 191 160 udpreceive 9997; +#X floatatom 522 305 5 0 0 0 - - -; +#X obj 414 278 unpack 0 0 0 0 0; +#X msg 191 90 status; +#X floatatom 293 225 9 0 0 0 - - -; +#X obj 474 251 tgl 15 0 empty empty empty 17 7 0 10 -4034 -1 -1 0 1 +; +#X floatatom 353 251 9 0 0 0 - - -; +#X text -10 90 get status on right outlet:; +#X text 186 225 bytes received:; +#X text 201 249 total bytes received:; +#X text 371 303 from:; +#X text 293 78 Specify a multicast address (from 224.0.0.0 to 239.255.255.255) +to use multicasting; +#X text 36 38 Creation arguments: port number to listen on (required) +; +#X obj 191 294 spigot; +#X obj 230 274 tgl 15 0 empty empty enable_print: -77 8 0 10 -4034 +-1 -1 0 1; +#X obj 191 319 print received; +#X obj 293 192 route received total from multicast; +#X text 175 56 IP address to listen on (optional); +#X msg 202 129 port 9998; +#X text 276 127 change port to listen on; +#X text 486 360 Martin Peach 2010/10/15; +#X text -12 3 [udpreceive] receives datagrams over a udp connection +and outputs them as raw bytes.; +#X connect 4 0 17 0; +#X connect 4 1 20 0; +#X connect 6 0 0 0; +#X connect 6 1 1 0; +#X connect 6 2 2 0; +#X connect 6 3 3 0; +#X connect 6 4 5 0; +#X connect 7 0 4 0; +#X connect 17 0 19 0; +#X connect 18 0 17 1; +#X connect 20 0 8 0; +#X connect 20 1 10 0; +#X connect 20 2 6 0; +#X connect 20 3 9 0; +#X connect 22 0 4 0; diff --git a/net/udpreceive.c b/net/udpreceive.c index e65d58f..09d31b8 100644 --- a/net/udpreceive.c +++ b/net/udpreceive.c @@ -38,14 +38,17 @@ typedef struct _udpreceive t_atom x_addrbytes[5]; t_atom x_msgoutbuf[MAX_UDP_RECEIVE]; char x_msginbuf[MAX_UDP_RECEIVE]; + char addr[256]; // a multicast address or 0 } t_udpreceive; void udpreceive_setup(void); static void udpreceive_free(t_udpreceive *x); static void *udpreceive_new(t_symbol *s, int argc, t_atom *argv); +static int udpreceive_new_socket(t_udpreceive *x, char *address, int port); static void udpreceive_sock_err(t_udpreceive *x, char *err_string); static void udpreceive_status(t_udpreceive *x); static void udpreceive_read(t_udpreceive *x, int sockfd); +static void udpreceive_port(t_udpreceive *x, t_float portno); static void udpreceive_read(t_udpreceive *x, int sockfd) { @@ -97,42 +100,75 @@ static void udpreceive_read(t_udpreceive *x, int sockfd) static void *udpreceive_new(t_symbol *s, int argc, t_atom *argv) { t_udpreceive *x; - struct sockaddr_in server; - struct hostent *hp; -#if defined __APPLE__ || defined _WIN32 - struct ip_mreq mreq; -#else - struct ip_mreqn mreq; -#endif - int sockfd, portno = 0; - int multicast_joined = 0; - int intarg, i; - char addr[256] = {'\0'}; + int result = 0, portno = 0; + int i; x = (t_udpreceive *)pd_new(udpreceive_class); /* if something fails we return 0 instead of x. Is this OK? */ + if (NULL == x) return x; + x->addr[0] = '\0'; + /* convert the bytes in the buffer to floats in a list */ + for (i = 0; i < MAX_UDP_RECEIVE; ++i) + { + x->x_msgoutbuf[i].a_type = A_FLOAT; + x->x_msgoutbuf[i].a_w.w_float = 0; + } + for (i = 0; i < 5; ++i) + { + x->x_addrbytes[i].a_type = A_FLOAT; + x->x_addrbytes[i].a_w.w_float = 0; + } #ifdef DEBUG post("udpreceive_new:argc is %d s is %s", argc, s->s_name); #endif for (i = 0; i < argc ;++i) { if (argv[i].a_type == A_FLOAT) - { + { // float is taken to be a port number #ifdef DEBUG post ("argv[%d] is a float: %f", i, argv[i].a_w.w_float); #endif portno = (int)argv[i].a_w.w_float; } else if (argv[i].a_type == A_SYMBOL) - { + { // symbol is taken to be an ip address (for multicast) #ifdef DEBUG post ("argv[%d] is a symbol: %s", i, argv[i].a_w.w_symbol->s_name); #endif - atom_string(&argv[i], addr, 256); + atom_string(&argv[i], x->addr, 256); } } #ifdef DEBUG - post("Setting port %d, address %s", portno, addr); + post("Setting port %d, address %s", portno, x->addr); +#endif + + x->x_msgout = outlet_new(&x->x_obj, &s_anything); + x->x_addrout = outlet_new(&x->x_obj, &s_anything); + + x->x_connectsocket = -1; // no socket + result = udpreceive_new_socket(x, x->addr, portno); + return (x); +} + +static int udpreceive_new_socket(t_udpreceive *x, char *address, int port) +{ +// return nonzero if successful in creating and binding a socket + int sockfd; + int intarg; + int multicast_joined = 0; + struct sockaddr_in server; + struct hostent *hp; +#if defined __APPLE__ || defined _WIN32 + struct ip_mreq mreq; +#else + struct ip_mreqn mreq; #endif + + if (x->x_connectsocket >= 0) + { + // close the existing socket first + sys_rmpollfn(x->x_connectsocket); + sys_closesocket(x->x_connectsocket); + } /* create a socket */ sockfd = socket(AF_INET, SOCK_DGRAM, 0); #ifdef DEBUG @@ -144,10 +180,10 @@ static void *udpreceive_new(t_symbol *s, int argc, t_atom *argv) return 0; } server.sin_family = AF_INET; - if (addr[0] == 0) server.sin_addr.s_addr = INADDR_ANY; + if (address[0] == 0) server.sin_addr.s_addr = INADDR_ANY; else { - hp = gethostbyname(addr); + hp = gethostbyname(address); if (hp == 0) { pd_error(x, "udpreceive: bad host?\n"); @@ -163,7 +199,7 @@ static void *udpreceive_new(t_symbol *s, int argc, t_atom *argv) udpreceive_sock_err(x, "udpreceive: setsockopt (SO_REUSEADDR) failed"); /* assign server port number */ - server.sin_port = htons((u_short)portno); + server.sin_port = htons((u_short)port); /* if a multicast address was specified, join the multicast group */ /* hop count defaults to 1 so we won't leave the subnet*/ @@ -175,7 +211,7 @@ static void *udpreceive_new(t_symbol *s, int argc, t_atom *argv) { udpreceive_sock_err(x, "udpreceive: bind"); sys_closesocket(sockfd); - return (0); + return 0; } /* second join the multicast group */ memcpy((char *)&server.sin_addr, (char *)hp->h_addr, hp->h_length); @@ -204,29 +240,14 @@ static void *udpreceive_new(t_symbol *s, int argc, t_atom *argv) { udpreceive_sock_err(x, "udpreceive: bind"); sys_closesocket(sockfd); - return (0); + return 0; } } - - x->x_msgout = outlet_new(&x->x_obj, &s_anything); - x->x_addrout = outlet_new(&x->x_obj, &s_anything); - x->x_connectsocket = sockfd; - - /* convert the bytes in the buffer to floats in a list */ - for (i = 0; i < MAX_UDP_RECEIVE; ++i) - { - x->x_msgoutbuf[i].a_type = A_FLOAT; - x->x_msgoutbuf[i].a_w.w_float = 0; - } - for (i = 0; i < 5; ++i) - { - x->x_addrbytes[i].a_type = A_FLOAT; - x->x_addrbytes[i].a_w.w_float = 0; - } x->x_multicast_joined = multicast_joined; + x->x_connectsocket = sockfd; x->x_total_received = 0L; sys_addpollfn(x->x_connectsocket, (t_fdpollfn)udpreceive_read, x); - return (x); + return 1; } static void udpreceive_sock_err(t_udpreceive *x, char *err_string) @@ -268,6 +289,12 @@ static void udpreceive_status(t_udpreceive *x) outlet_anything( x->x_addrout, gensym("total"), 1, &output_atom); } +static void udpreceive_port(t_udpreceive *x, t_float portno) +{ + int result; + result = udpreceive_new_socket(x, x->addr, (int)portno); +} + static void udpreceive_free(t_udpreceive *x) { if (x->x_connectsocket >= 0) @@ -284,6 +311,8 @@ void udpreceive_setup(void) sizeof(t_udpreceive), CLASS_DEFAULT, A_GIMME, 0); class_addmethod(udpreceive_class, (t_method)udpreceive_status, gensym("status"), 0); + class_addmethod(udpreceive_class, (t_method)udpreceive_port, + gensym("port"), A_DEFFLOAT, 0); } /* end udpreceive.c */ |