From e6f799e41d7910e1388c68630c49bf3141cb8d9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?IOhannes=20m=20zm=C3=B6lnig?= Date: Tue, 1 Sep 2015 14:30:54 +0000 Subject: sync with git svn path=/trunk/externals/iem/iemnet/; revision=17545 --- ChangeLog | 13 ++++++- Makefile | 57 ++++++++++++++++-------------- iemnet-meta.pd | 2 +- iemnet.c | 54 ++++++++++++++++++++++++---- iemnet.h | 9 ++++- iemnet_data.c | 2 +- iemnet_receiver.c | 2 +- iemnet_sender.c | 6 ++-- tcpclient.c | 19 +++++----- tcpreceive.c | 44 +++++++++++------------ tcpsend.c | 30 ++++++++-------- tcpserver.c | 104 ++++++++++++++++++++++-------------------------------- udpreceive.c | 33 +++++++++++------ udpsend.c | 77 ++++++++++++++++++---------------------- udpserver.c | 75 ++++++++++++++++++--------------------- udpsndrcv-help.pd | 59 +++++++++++++++++++++++++++++++ udpsndrcv.pd | 71 +++++++++++++++++++++++++++++++++++++ 17 files changed, 410 insertions(+), 247 deletions(-) create mode 100644 udpsndrcv-help.pd create mode 100644 udpsndrcv.pd diff --git a/ChangeLog b/ChangeLog index 2802724..1e2bdab 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2015-09-01 12:00 zmoelnig + + * iemnet-v0.2 + + got rid of threaded receiver + - simplifies code + - fixes a couple of stability bugs + - compiles again on W32 + one-true-brace-style + reproducible build + 2010-10-11 16:04 zmoelnig * tcpreceive.c, udpreceive.c: use SO_REUSEPORT (if available during @@ -199,7 +210,7 @@ 2010-08-09 09:22 zmoelnig - * iemnet_data.c: allow to resize NULL-floatlists + * iemnet_data.c: allow resizing of NULL-floatlists trying to resize a NULL-floatlist, will create a new one with the required size diff --git a/Makefile b/Makefile index 41ec52d..5815377 100644 --- a/Makefile +++ b/Makefile @@ -25,11 +25,12 @@ SHARED_HEADERS = iemnet_data.h iemnet.h # list them here. This can be anything from header files, test patches, # documentation, etc. README.txt and LICENSE.txt are required and therefore # automatically included -EXTRA_DIST = - +EXTRA_DIST = ChangeLog FEATURES.txt NOTES.txt LIBS_windows=-lpthread +#overriding the datestring +# run `make CPPFLAGS="-DBUILD_DATE='\"somewhen in August\"'"` #------------------------------------------------------------------------------# @@ -236,60 +237,63 @@ endif # in case somebody manually set the HELPPATCHES above HELPPATCHES ?= $(SOURCES:.c=-help.pd) $(PDOBJECTS:.pd=-help.pd) -ALL_CFLAGS := $(ALL_CFLAGS) $(CFLAGS) $(OPT_CFLAGS) -ALL_LDFLAGS := $(LDFLAGS) $(ALL_LDFLAGS) -ALL_LIBS := $(LIBS) $(ALL_LIBS) +ALL_CFLAGS := $(CPPFLAGS) $(ALL_CFLAGS) $(OPT_CFLAGS) $(CFLAGS) +ALL_LDFLAGS := $(ALL_LDFLAGS) $(LDFLAGS) +ALL_LIBS := $(ALL_LIBS) $(LIBS) SHARED_SOURCES ?= $(shell test ! -e lib$(LIBRARY_NAME).c || \ echo lib$(LIBRARY_NAME).c ) SHARED_HEADERS ?= $(shell test ! -e $(LIBRARY_NAME).h || echo $(LIBRARY_NAME).h) SHARED_LIB ?= lib$(LIBRARY_NAME:=.$(SHARED_EXTENSION)) -.PHONY = install libdir_install single_install install-doc install-examples install-manual clean distclean dist etags $(LIBRARY_NAME) +.PHONY = all clean distclean install dist \ + etags dpkg-source showsetup \ + libdir_install install-objects \ + single_install install-libobject \ + install-doc install-examples install-manual \ + libdir $(LIBRARY_NAME) all: $(SOURCES:.c=.$(EXTENSION)) $(SHARED_LIB) %.o: %.c $(SHARED_HEADERS) - $(CC) $(ALL_CFLAGS) -o "$*.o" -c "$*.c" + $(CC) $(ALL_CFLAGS) -o $@ -c $< %.$(EXTENSION): %.o $(SHARED_LIB) - $(CC) $(ALL_LDFLAGS) -o "$*.$(EXTENSION)" "$*.o" $(ALL_LIBS) $(SHARED_LIB) - chmod a-x "$*.$(EXTENSION)" + $(CC) $(ALL_LDFLAGS) -o $@ $^ $(ALL_LIBS) + chmod a-x $@ # this links everything into a single binary file -$(LIBRARY_NAME): $(SOURCES:.c=.o) $(LIBRARY_NAME).o - $(CC) $(ALL_LDFLAGS) -o $(LIBRARY_NAME).$(EXTENSION) $(SOURCES:.c=.o) $(LIBRARY_NAME).o $(ALL_LIBS) - chmod a-x $(LIBRARY_NAME).$(EXTENSION) +$(LIBRARY_NAME): $(LIBRARY_NAME).$(EXTENSION) + +$(LIBRARY_NAME).$(EXTENSION): $(SOURCES:.c=.o) $(LIBRARY_NAME).o + $(CC) $(ALL_LDFLAGS) -o $@ $^ $(ALL_LIBS) + chmod a-x $@ $(SHARED_LIB): $(SHARED_SOURCES:.c=.o) - $(CC) $(SHARED_LDFLAGS) -o $(SHARED_LIB) $(SHARED_SOURCES:.c=.o) $(ALL_LIBS) + $(CC) $(SHARED_LDFLAGS) -o $@ $^ $(ALL_LIBS) install: libdir_install # The meta and help files are explicitly installed to make sure they are # actually there. Those files are not optional, then need to be there. -libdir_install: $(SOURCES:.c=.$(EXTENSION)) $(SHARED_LIB) install-doc install-examples install-manual +install-objects: $(SOURCES:.c=.$(EXTENSION)) $(SHARED_LIB) $(PDOBJECTS) $(SHARED_TCL_LIB) $(INSTALL_DIR) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME) $(INSTALL_DATA) $(LIBRARY_NAME)-meta.pd \ $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME) - test -z "$(strip $(SOURCES))" || (\ - $(INSTALL_PROGRAM) $(SOURCES:.c=.$(EXTENSION)) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME) && \ - $(STRIP) $(addprefix $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/,$(SOURCES:.c=.$(EXTENSION)))) - test -z "$(strip $(SHARED_LIB))" || \ - $(INSTALL_DATA) $(SHARED_LIB) \ - $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME) + $(INSTALL_DATA) $^ \ + $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME) test -z "$(strip $(wildcard $(SOURCES:.c=.tcl)))" || \ $(INSTALL_DATA) $(wildcard $(SOURCES:.c=.tcl)) \ $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME) - test -z "$(strip $(PDOBJECTS))" || \ - $(INSTALL_DATA) $(PDOBJECTS) \ - $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME) +libdir_install: install-objects install-doc install-examples install-manual # install library linked as single binary -single_install: $(LIBRARY_NAME) install-doc install-examples install-manual +install-libobject: $(LIBRARY_NAME).$(EXTENSION) $(INSTALL_DIR) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME) - $(INSTALL_PROGRAM) $(LIBRARY_NAME).$(EXTENSION) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME) - $(STRIP) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/$(LIBRARY_NAME).$(EXTENSION) + $(INSTALL_PROGRAM) $^ $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME) + -$(STRIP) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/$(LIBRARY_NAME).$(EXTENSION) + +single_install: install-libobject install-doc install-examples install-manual install-doc: $(INSTALL_DIR) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME) @@ -298,6 +302,7 @@ install-doc: $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME) $(INSTALL_DATA) README.txt $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/README.txt $(INSTALL_DATA) LICENSE.txt $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/LICENSE.txt + $(INSTALL_DATA) ChangeLog $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/CHANGES.txt install-examples: test -z "$(strip $(EXAMPLES))" || \ diff --git a/iemnet-meta.pd b/iemnet-meta.pd index cf00c23..26b2760 100644 --- a/iemnet-meta.pd +++ b/iemnet-meta.pd @@ -4,7 +4,7 @@ Music and Acoustics (IEM) \, University of Music and Performing Arts \, Graz \, Austria; #N canvas 25 49 420 300 META 0; -#X text 10 10 VERSION 0.1; +#X text 10 10 VERSION 0.2; #X text 10 30 AUTHOR IOhannes m zmoelnig ; #X text 10 50 NAME iemnet; #X text 10 70 LICENSE GPL-2; diff --git a/iemnet.c b/iemnet.c index 2ad4d70..ce8cf4b 100644 --- a/iemnet.c +++ b/iemnet.c @@ -1,7 +1,7 @@ /* iemnet * this file provides core infrastructure for the iemnet-objects * - * copyright (c) 2010-2011 IOhannes m zmölnig, IEM + * copyright © 2010-2015 IOhannes m zmölnig, IEM */ /* This program is free software; you can redistribute it and/or */ @@ -151,17 +151,21 @@ static int iemnet__nametaken(const char*namestring) return 0; } +#ifndef BUILD_DATE +# define BUILD_DATE "on " __DATE__ " at " __TIME__ +#endif + int iemnet__register(const char*name) { if(iemnet__nametaken(name)) { return 0; } post("iemnet - networking with Pd: [%s]", name); -#ifdef LIBRARY_VERSION - post(" version "LIBRARY_VERSION""); +#ifdef VERSION + post(" version "VERSION""); #endif - post(" compiled on "__DATE__" at " __TIME__""); - post(" copyright (c) 2010-2011 IOhannes m zmoelnig, IEM"); + post(" compiled "BUILD_DATE""); + post(" copyright © 2010-2015 IOhannes m zmoelnig, IEM"); post(" based on mrpeach/net, based on maxlib"); return 1; } @@ -197,7 +201,7 @@ void iemnet_debuglevel(void*x, t_float f) post("iemnet: setting debuglevel to %d", debuglevel); #else if(firsttime) { - post("iemnet compiled without debug!"); + error("iemnet compiled without debug!"); } #endif firsttime=0; @@ -233,3 +237,41 @@ IEMNET_EXTERN void iemnet_setup(void) udpserver_setup(); #endif } + +#include +#include +#include + +void iemnet_log(const void *object, const t_iemnet_loglevel level, const char *fmt, ...) +{ + t_pd*x=(t_pd*)object; + const char*name=x?((*x)->c_name->s_name):0; + char buf[MAXPDSTRING]; + va_list ap; + t_int arg[8]; + va_start(ap, fmt); + vsnprintf(buf, MAXPDSTRING-1, fmt, ap); + va_end(ap); + strcat(buf, "\0"); +#if (defined PD_MINOR_VERSION) && (PD_MINOR_VERSION >= 43) + if (name) { + logpost(x, level, "[%s]: %s", name, buf); + } else { + logpost(x, level, "%s", buf); + } +#else + if (name) { + if(level>1) { + post("[%s]: %s", name, buf); + } else { + pd_error(x, "[%s]: %s", name, buf); + } + } else { + if(level>1) { + post("%s", name, buf); + } else { + pd_error(x, "%s", name, buf); + } + } +#endif +} diff --git a/iemnet.h b/iemnet.h index 614b286..4a54720 100644 --- a/iemnet.h +++ b/iemnet.h @@ -257,7 +257,14 @@ int iemnet__register(const char*name); static void autoinit__ ## f(void) { f(); } #endif - +typedef enum { + IEMNET_FATAL = 0, + IEMNET_ERROR = 1, + IEMNET_NORMAL = 2, + IEMNET_VERBOSE = 3, + IEMNET_DEBUG = 4 +} t_iemnet_loglevel; +void iemnet_log(const void *object, const t_iemnet_loglevel level, const char *fmt, ...); /** * \fn void DEBUG(const char* format,...); * diff --git a/iemnet_data.c b/iemnet_data.c index f0dea5f..e894bed 100644 --- a/iemnet_data.c +++ b/iemnet_data.c @@ -4,7 +4,7 @@ * - wrappers for data "chunks" * - queues * - * copyright (c) 2010 IOhannes m zmölnig, IEM + * copyright © 2010-2015 IOhannes m zmölnig, IEM */ /* This program is free software; you can redistribute it and/or */ diff --git a/iemnet_receiver.c b/iemnet_receiver.c index 898bac8..442b055 100644 --- a/iemnet_receiver.c +++ b/iemnet_receiver.c @@ -3,7 +3,7 @@ * receiver * receives data "chunks" from a socket * - * copyright (c) 2010-2015 IOhannes m zmölnig, IEM + * copyright © 2010-2015 IOhannes m zmölnig, IEM */ /* This program is free software; you can redistribute it and/or */ diff --git a/iemnet_sender.c b/iemnet_sender.c index 8cf1d14..7c3c5d4 100644 --- a/iemnet_sender.c +++ b/iemnet_sender.c @@ -4,7 +4,7 @@ * sends data "chunks" to a socket * possibly threaded * - * copyright (c) 2010 IOhannes m zmölnig, IEM + * copyright © 2010-2015 IOhannes m zmölnig, IEM */ /* This program is free software; you can redistribute it and/or */ @@ -277,7 +277,7 @@ int iemnet__sender_getsockopt(t_iemnet_sender*s, int level, int optname, { int result=getsockopt(s->sockfd, level, optname, optval, optlen); if(result!=0) { - post("%s: getsockopt returned %d", __FUNCTION__, + error("iemnet::sender: getsockopt returned %d", iemnet__sender_getlasterror(s)); } return result; @@ -287,7 +287,7 @@ int iemnet__sender_setsockopt(t_iemnet_sender*s, int level, int optname, { int result=setsockopt(s->sockfd, level, optname, optval, optlen); if(result!=0) { - post("%s: setsockopt returned %d", __FUNCTION__, + error("iemnet::sender: setsockopt returned %d", iemnet__sender_getlasterror(s)); } return result; diff --git a/tcpclient.c b/tcpclient.c index a1519b1..40a32ea 100644 --- a/tcpclient.c +++ b/tcpclient.c @@ -1,5 +1,5 @@ /* tcpclient.c - * copyright (c) 2010 IOhannes m zmölnig, IEM + * copyright © 2010-2015 IOhannes m zmölnig, IEM * copyright (c) 2006-2010 Martin Peach * copyright (c) 2004 Olaf Matthes */ @@ -116,14 +116,15 @@ static int tcpclient_do_connect(const char*host, unsigned short port, server.sin_family = AF_INET; hp = gethostbyname(host); if (hp == 0) { - sys_sockerror("tcpclient: bad host?\n"); + iemnet_log(x, IEMNET_ERROR, "bad host '%s'?", host); return (-1); } memcpy((char *)&server.sin_addr, (char *)hp->h_addr, hp->h_length); sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) { - sys_sockerror("tcpclient: socket"); + iemnet_log(x, IEMNET_ERROR, "unable to open socket"); + sys_sockerror("socket"); return (sockfd); } @@ -132,7 +133,8 @@ static int tcpclient_do_connect(const char*host, unsigned short port, /* try to connect */ if (connect(sockfd, (struct sockaddr *) &server, sizeof (server)) < 0) { - sys_sockerror("tcpclient: connecting stream socket"); + iemnet_log(x, IEMNET_ERROR, "unable to connect to stream socket"); + sys_sockerror("connect"); iemnet__closesocket(sockfd); return (-1); } @@ -166,14 +168,12 @@ static void tcpclient_connect(t_tcpclient *x, t_symbol *hostname, { long addr=0; int state; + + // first disconnect any active connection if(x->x_hostname || x->x_port) { state=tcpclient_do_disconnect(x->x_fd, x->x_sender, x->x_receiver); if(state) { outlet_float(x->x_connectout, 0); - } else { - if(!x->x_port) { - pd_error(x, "[%s]: not connected", objName); - } } } @@ -191,7 +191,6 @@ static void tcpclient_connect(t_tcpclient *x, t_symbol *hostname, if(state>0) { outlet_float(x->x_connectout, 1); } - } static void tcpclient_disconnect(t_tcpclient *x) @@ -200,7 +199,7 @@ static void tcpclient_disconnect(t_tcpclient *x) int state=tcpclient_do_disconnect(x->x_fd, x->x_sender, x->x_receiver); if(!state && !x->x_port) { - pd_error(x, "[%s]: not connected", objName); + iemnet_log(x, IEMNET_ERROR, "not connected"); } } outlet_float(x->x_connectout, 0); diff --git a/tcpreceive.c b/tcpreceive.c index a115a06..fb7c54d 100644 --- a/tcpreceive.c +++ b/tcpreceive.c @@ -1,5 +1,5 @@ /* tcpreceive.c - * copyright (c) 2010 IOhannes m zmölnig, IEM + * copyright © 2010-2015 IOhannes m zmölnig, IEM * copyright (c) 2006-2010 Martin Peach * copyright (c) Miller Puckette */ @@ -65,6 +65,8 @@ typedef struct _tcpreceive { t_iemnet_floatlist *x_floatlist; } t_tcpreceive; +/* forward declarations */ +static int tcpreceive_disconnect(t_tcpreceive *x, int id); static int tcpreceive_find_socket(t_tcpreceive *x, int fd) { @@ -77,8 +79,6 @@ static int tcpreceive_find_socket(t_tcpreceive *x, int fd) return -1; } -static int tcpreceive_disconnect(t_tcpreceive *x, int id); - static void tcpreceive_read_callback(void *w, t_iemnet_chunk*c) { t_tcpconnection*y=(t_tcpconnection*)w; @@ -120,7 +120,6 @@ static int tcpreceive_addconnection(t_tcpreceive *x, int fd, long addr, x->x_connection+i, tcpreceive_read_callback, 0); - return 1; } } @@ -140,7 +139,8 @@ static void tcpreceive_connectpoll(t_tcpreceive *x) fd = accept(x->x_connectsocket, (struct sockaddr *)&from, &fromlen); if (fd < 0) { - error("[%s] accept failed", objName); + iemnet_log(x, IEMNET_ERROR, "could not accept new connection"); + sys_sockerror("accept"); } else { /* get the sender's ip */ addr = ntohl(from.sin_addr.s_addr); @@ -150,13 +150,12 @@ static void tcpreceive_connectpoll(t_tcpreceive *x) outlet_float(x->x_connectout, x->x_nconnections); iemnet__addrout(x->x_statout, x->x_addrout, addr, port); } else { - error ("[%s] Too many connections", objName); + iemnet_log(x, IEMNET_ERROR, "too many connections"); iemnet__closesocket(fd); } } } - static int tcpreceive_disconnect(t_tcpreceive *x, int id) { if(id>=0 && id < MAX_CONNECTIONS && x->x_connection[id].port>0) { @@ -176,6 +175,7 @@ static int tcpreceive_disconnect(t_tcpreceive *x, int id) return 0; } + /* tcpreceive_closeall closes all open sockets and deletes them from the list */ static void tcpreceive_disconnect_all(t_tcpreceive *x) { @@ -186,9 +186,6 @@ static void tcpreceive_disconnect_all(t_tcpreceive *x) } } - - - /* tcpreceive_removeconnection tries to delete the socket fd from the list */ /* returns 1 on success, else 0 */ static int tcpreceive_disconnect_socket(t_tcpreceive *x, int fd) @@ -225,10 +222,10 @@ static void tcpreceive_port(t_tcpreceive*x, t_floatarg fportno) x->x_port=-1; } - sockfd = socket(AF_INET, SOCK_STREAM, 0); if(sockfd<0) { - error("[%s]: unable to create socket", objName); + iemnet_log(x, IEMNET_ERROR, "unable to create socket"); + sys_sockerror("socket"); return; } @@ -238,7 +235,8 @@ static void tcpreceive_port(t_tcpreceive*x, t_floatarg fportno) if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char *)&intarg, sizeof(intarg)) < 0) { - error("[%s]: setsockopt (SO_REUSEADDR) failed", objName); + iemnet_log(x, IEMNET_ERROR, "unable to enable address re-using"); + sys_sockerror("setsockopt:SO_REUSEADDR"); } #endif /* SO_REUSEADDR */ #ifdef SO_REUSEPORT @@ -246,7 +244,8 @@ static void tcpreceive_port(t_tcpreceive*x, t_floatarg fportno) if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEPORT, (char *)&intarg, sizeof(intarg)) < 0) { - error("[%s]: setsockopt (SO_REUSEPORT) failed", objName); + iemnet_log(x, IEMNET_ERROR, "unable to enable port re-using"); + sys_sockerror("setsockopt:SO_REUSEPORT"); } #endif /* SO_REUSEPORT */ @@ -254,17 +253,18 @@ static void tcpreceive_port(t_tcpreceive*x, t_floatarg fportno) intarg = 1; if (setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, (char *)&intarg, sizeof(intarg)) < 0) { - post("[%s]: setsockopt (TCP_NODELAY) failed", objName); + iemnet_log(x, IEMNET_ERROR, "unable to enable immediate sending"); + sys_sockerror("setsockopt:TCP_NODELAY"); } - server.sin_family = AF_INET; server.sin_addr.s_addr = INADDR_ANY; server.sin_port = htons((u_short)portno); /* name the socket */ if (bind(sockfd, (struct sockaddr *)&server, serversize) < 0) { - sys_sockerror("[tcpreceive] bind failed"); + iemnet_log(x, IEMNET_ERROR, "couldn't bind socket"); + sys_sockerror("bind"); iemnet__closesocket(sockfd); sockfd = -1; outlet_anything(x->x_statout, gensym("port"), 1, ap); @@ -273,7 +273,8 @@ static void tcpreceive_port(t_tcpreceive*x, t_floatarg fportno) /* streaming protocol */ if (listen(sockfd, 5) < 0) { - sys_sockerror("[tcpreceive] listen"); + iemnet_log(x, IEMNET_ERROR, "unable to listen on socket"); + sys_sockerror("listen"); iemnet__closesocket(sockfd); sockfd = -1; outlet_anything(x->x_statout, gensym("port"), 1, ap); @@ -292,7 +293,6 @@ static void tcpreceive_port(t_tcpreceive*x, t_floatarg fportno) x->x_port=ntohs(server.sin_port); } - SETFLOAT(ap, x->x_port); outlet_anything(x->x_statout, gensym("port"), 1, ap); } @@ -302,7 +302,6 @@ static void tcpreceive_serialize(t_tcpreceive *x, t_floatarg doit) x->x_serialize=doit; } - static void tcpreceive_free(t_tcpreceive *x) { /* is this ever called? */ @@ -327,7 +326,7 @@ static void *tcpreceive_new(t_floatarg fportno) x->x_msgout = outlet_new(&x->x_obj, 0); x->x_addrout = outlet_new(&x->x_obj, gensym("list")); /* legacy */ x->x_connectout = outlet_new(&x->x_obj, gensym("float")); /* legacy */ - x->x_statout = outlet_new(&x->x_obj, 0);/* outlet for everything else */ + x->x_statout = outlet_new(&x->x_obj, 0); /* outlet for everything else */ x->x_serialize=1; @@ -371,7 +370,4 @@ IEMNET_EXTERN void tcpreceive_setup(void) IEMNET_INITIALIZER(tcpreceive_setup); - /* end x_net_tcpreceive.c */ - - diff --git a/tcpsend.c b/tcpsend.c index 664137c..f35c4e1 100644 --- a/tcpsend.c +++ b/tcpsend.c @@ -1,5 +1,5 @@ /* tcpsend.c - * copyright (c) 2010 IOhannes m zmölnig, IEM + * copyright © 2010-2015 IOhannes m zmölnig, IEM * copyright (c) 2006-2010 Martin Peach * copyright (c) Miller Puckette */ @@ -33,7 +33,6 @@ static const char objName[] = "tcpsend"; # include #endif - static t_class *tcpsend_class; typedef struct _tcpsend { @@ -44,20 +43,17 @@ typedef struct _tcpsend { static void tcpsend_disconnect(t_tcpsend *x) { + if(x->x_sender) { + iemnet__sender_destroy(x->x_sender, 0); + } + x->x_sender=NULL; if (x->x_fd >= 0) { - if(x->x_sender) { - iemnet__sender_destroy(x->x_sender, 0); - } - x->x_sender=NULL; iemnet__closesocket(x->x_fd); x->x_fd = -1; outlet_float(x->x_obj.ob_outlet, 0); - //post("tcpsend: disconnected"); } } - - static void tcpsend_connect(t_tcpsend *x, t_symbol *hostname, t_floatarg fportno) { @@ -69,7 +65,7 @@ static void tcpsend_connect(t_tcpsend *x, t_symbol *hostname, memset(&server, 0, sizeof(server)); if (x->x_fd >= 0) { - error("tcpsend: already connected"); + iemnet_log(x, IEMNET_ERROR, "already connected"); return; } @@ -77,21 +73,23 @@ static void tcpsend_connect(t_tcpsend *x, t_symbol *hostname, sockfd = socket(AF_INET, SOCK_STREAM, 0); DEBUG("send socket %d\n", sockfd); if (sockfd < 0) { - sys_sockerror("tcpsend: socket"); + iemnet_log(x, IEMNET_ERROR, "unable to open socket"); + sys_sockerror("socket"); return; } /* connect socket using hostname provided in command line */ server.sin_family = AF_INET; hp = gethostbyname(hostname->s_name); if (hp == 0) { - post("tcpsend: bad host?\n"); + iemnet_log(x, IEMNET_ERROR, "bad host '%s'?", hostname->s_name); return; } /* for stream (TCP) sockets, specify "nodelay" */ intarg = 1; if (setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, (char *)&intarg, sizeof(intarg)) < 0) { - post("tcpsend: setsockopt (TCP_NODELAY) failed\n"); + iemnet_log(x, IEMNET_ERROR, "unable to enable immediate sending"); + sys_sockerror("setsockopt"); } memcpy((char *)&server.sin_addr, (char *)hp->h_addr, hp->h_length); @@ -99,10 +97,11 @@ static void tcpsend_connect(t_tcpsend *x, t_symbol *hostname, /* assign client port number */ server.sin_port = htons((u_short)portno); - post("tcpsend: connecting to port %d", portno); + iemnet_log(x, IEMNET_VERBOSE, "connecting to port %d", portno); /* try to connect. */ if (connect(sockfd, (struct sockaddr *) &server, sizeof (server)) < 0) { - sys_sockerror("tcpsend: connecting stream socket"); + iemnet_log(x, IEMNET_ERROR, "unable to initiate connection on socket %d", sockfd); + sys_sockerror("connect"); iemnet__closesocket(sockfd); return; } @@ -160,5 +159,4 @@ IEMNET_EXTERN void tcpsend_setup(void) IEMNET_INITIALIZER(tcpsend_setup); - /* end tcpsend.c */ diff --git a/tcpserver.c b/tcpserver.c index ca4f38e..218b6ba 100644 --- a/tcpserver.c +++ b/tcpserver.c @@ -1,5 +1,5 @@ /* tcpserver.c - * copyright (c) 2010 IOhannes m zmölnig, IEM + * copyright © 2010-2015 IOhannes m zmölnig, IEM * copyright (c) 2006-2010 Martin Peach * copyright (c) 2004 Olaf Matthes */ @@ -71,6 +71,7 @@ typedef struct _tcpserver { t_iemnet_floatlist *x_floatlist; } t_tcpserver; +/* forward declarations */ static void tcpserver_receive_callback(void*x, t_iemnet_chunk*); static t_tcpserver_socketreceiver *tcpserver_socketreceiver_new( @@ -79,21 +80,19 @@ static t_tcpserver_socketreceiver *tcpserver_socketreceiver_new( t_tcpserver_socketreceiver *x = (t_tcpserver_socketreceiver *)getbytes( sizeof(*x)); if(NULL==x) { - error("%s_socketreceiver: unable to allocate %d bytes", objName, - (int)sizeof(*x)); + iemnet_log(x, IEMNET_FATAL, "unable to allocate %d bytes", (int)sizeof(*x)); return NULL; - } else { - x->sr_owner=owner; + } + x->sr_owner=owner; - x->sr_fd=sockfd; + x->sr_fd=sockfd; - x->sr_host=ntohl(addr->sin_addr.s_addr); - x->sr_port=ntohs(addr->sin_port); + x->sr_host=ntohl(addr->sin_addr.s_addr); + x->sr_port=ntohs(addr->sin_port); - x->sr_sender=iemnet__sender_create(sockfd, NULL, NULL, 0); - x->sr_receiver=iemnet__receiver_create(sockfd, x, - tcpserver_receive_callback, 0); - } + x->sr_sender=iemnet__sender_create(sockfd, NULL, NULL, 0); + x->sr_receiver=iemnet__receiver_create(sockfd, x, + tcpserver_receive_callback, 0); return (x); } @@ -111,7 +110,6 @@ static void tcpserver_socketreceiver_free(t_tcpserver_socketreceiver *x) x->sr_fd=-1; - if(sender) { iemnet__sender_destroy(sender, 0); } @@ -121,10 +119,9 @@ static void tcpserver_socketreceiver_free(t_tcpserver_socketreceiver *x) iemnet__closesocket(sockfd); - freebytes(x, sizeof(*x)); } - DEBUG("freeed %x", x); + DEBUG("freed %x", x); } static int tcpserver_socket2index(t_tcpserver*x, int sockfd) @@ -145,19 +142,19 @@ static int tcpserver_socket2index(t_tcpserver*x, int sockfd) static int tcpserver_fixindex(t_tcpserver*x, int client) { if(x->x_nconnections <= 0) { - pd_error(x, "[%s]: no clients connected", objName); + iemnet_log(x, IEMNET_ERROR, "no clients connected"); return -1; } - if (!((client > 0) && (client <= x->x_nconnections))) { - pd_error(x, "[%s] client %d out of range [1..%d]", objName, client, - (int)(x->x_nconnections)); + if (!((client > 0) && ((unsigned int)client <= x->x_nconnections))) { + iemnet_log(x, IEMNET_ERROR, + "client:%d out of range [1..%d]", + client, (int)(x->x_nconnections)); return -1; } return (client-1); } - /* ---------------- tcpserver info ---------------------------- */ static void tcpserver_info_client(t_tcpserver *x, unsigned int client) { @@ -194,18 +191,16 @@ static void tcpserver_info_client(t_tcpserver *x, unsigned int client) } } - static void tcpserver_info(t_tcpserver *x) { static t_atom output_atom[4]; int sockfd=x->x_connectsocket; - int port=x->x_port; if(sockfd<0) { - // no open port - post("no valid sock"); + iemnet_log(x, IEMNET_ERROR, "no open socket"); + return; } if(x->x_port<=0) { @@ -215,7 +210,9 @@ static void tcpserver_info(t_tcpserver *x) x->x_port=ntohs(server.sin_port); port=x->x_port; } else { - post("gesockname failed for %d", sockfd); + iemnet_log(x, IEMNET_ERROR, "unable to get socket name for %d", sockfd); + sys_sockerror("getsockname"); + return; } } @@ -223,7 +220,6 @@ static void tcpserver_info(t_tcpserver *x) outlet_anything( x->x_statout, gensym("port"), 1, output_atom); } - static void tcpserver_info_connection(t_tcpserver *x, t_tcpserver_socketreceiver*y) { @@ -375,9 +371,6 @@ static void tcpserver_broadcastbut(t_tcpserver *x, t_symbol *s, int argc, t_atom *argv) { int but=-1; - //int client=0; - // t_iemnet_chunk*chunk=NULL; - if(argc<2) { return; } @@ -398,8 +391,7 @@ static void tcpserver_defaultsend(t_tcpserver *x, t_symbol *s, int argc, tcpserver_send_toclient(x, client, argc, argv); return; } - pd_error(x, "[%s] illegal socket %d, switching to broadcast mode", objName, - sockfd); + iemnet_log(x, IEMNET_ERROR, "illegal socket:%d, switching to broadcast mode", sockfd); x->x_defaulttarget=0; } else if(sockfd<0) { client=tcpserver_socket2index(x, -sockfd); @@ -407,8 +399,7 @@ static void tcpserver_defaultsend(t_tcpserver *x, t_symbol *s, int argc, tcpserver_send_butclient(x, client, argc, argv); return; } - pd_error(x, "[%s] illegal !ocket %d, switching to broadcast mode", objName, - sockfd); + iemnet_log(x, IEMNET_ERROR, "illegal socket:%d excluded, switching to broadcast mode", sockfd); x->x_defaulttarget=0; } @@ -421,8 +412,9 @@ static void tcpserver_defaulttarget(t_tcpserver *x, t_floatarg f) unsigned int client=(rawclient<0)?(-rawclient):rawclient; if(client > x->x_nconnections) { - error("[%s] target %d out of range [0..%d]", objName, client, - (int)(x->x_nconnections)); + iemnet_log(x, IEMNET_ERROR, + "target %d out of range [0..%d]", + client, (int)(x->x_nconnections)); return; } @@ -443,8 +435,6 @@ static void tcpserver_targetsocket(t_tcpserver *x, t_floatarg f) x->x_defaulttarget=sockfd; } - - /* send message to client using socket number */ static void tcpserver_send_socket(t_tcpserver *x, t_symbol *s, int argc, t_atom *argv) @@ -457,7 +447,7 @@ static void tcpserver_send_socket(t_tcpserver *x, t_symbol *s, int argc, return; } } else { - pd_error(x, "%s_send: no socket specified", objName); + iemnet_log(x, IEMNET_ERROR, "no socket specified"); return; } @@ -466,11 +456,11 @@ static void tcpserver_send_socket(t_tcpserver *x, t_symbol *s, int argc, int sockfd=atom_getint(argv); client = tcpserver_socket2index(x, sockfd); if(client < 0) { - post("%s_send: no connection on socket %d", objName, sockfd); + iemnet_log(x, IEMNET_ERROR, "no connection on socket %d", sockfd); return; } } else { - post("%s_send: no socket specified", objName); + iemnet_log(x, IEMNET_ERROR, "only numeric sockets allowed"); return; } @@ -495,11 +485,9 @@ static void tcpserver_disconnect(t_tcpserver *x, unsigned int client) x->x_sr[k + 1]=NULL; x->x_nconnections--; - outlet_float(x->x_connectout, x->x_nconnections); } - /* disconnect a client by number */ static void tcpserver_disconnect_client(t_tcpserver *x, t_floatarg fclient) { @@ -511,7 +499,6 @@ static void tcpserver_disconnect_client(t_tcpserver *x, t_floatarg fclient) tcpserver_disconnect(x, client); } - /* disconnect a client by socket */ static void tcpserver_disconnect_socket(t_tcpserver *x, t_floatarg fsocket) { @@ -521,8 +508,6 @@ static void tcpserver_disconnect_socket(t_tcpserver *x, t_floatarg fsocket) } } - - /* disconnect a client by socket */ static void tcpserver_disconnect_all(t_tcpserver *x) { @@ -551,11 +536,9 @@ static void tcpserver_receive_callback(void *y0, } else { // disconnected int sockfd=y->sr_fd; - verbose(1, "[%s] got disconnection for socket:%d", objName, sockfd); + iemnet_log(x, IEMNET_VERBOSE, "got disconnection for socket:%d", sockfd); tcpserver_disconnect_socket(x, sockfd); } - - // post("tcpserver: %d bytes in %d packets", bytecount, packetcount); } static void tcpserver_connectpoll(t_tcpserver *x) @@ -571,12 +554,12 @@ static void tcpserver_connectpoll(t_tcpserver *x) } else { t_tcpserver_socketreceiver *y = NULL; if(x->x_nconnections>=MAX_CONNECT) { - pd_error(x, "%s: cannot handle more than %d connections, dropping", - objName, x->x_nconnections); + iemnet_log(x, IEMNET_ERROR, + "cannot handle more than %d connections, dropping!", + x->x_nconnections); iemnet__closesocket(fd); } - y = tcpserver_socketreceiver_new((void *)x, fd, &incomer_address); if (!y) { iemnet__closesocket(fd); @@ -616,7 +599,8 @@ static void tcpserver_port(t_tcpserver*x, t_floatarg fportno) sockfd = socket(AF_INET, SOCK_STREAM, 0); if(sockfd<0) { - sys_sockerror("[tcpserver]: cannot create TCP/IP socket"); + iemnet_log(x, IEMNET_ERROR, "unable to create TCP/IP socket"); + sys_sockerror("socket"); return; } @@ -629,7 +613,8 @@ static void tcpserver_port(t_tcpserver*x, t_floatarg fportno) server.sin_port = htons((u_short)portno); /* name the socket */ if (bind(sockfd, (struct sockaddr *)&server, serversize) < 0) { - sys_sockerror("tcpserver: bind"); + iemnet_log(x, IEMNET_ERROR, "unable to bind to TCP/IP socket"); + sys_sockerror("bind"); iemnet__closesocket(sockfd); outlet_anything(x->x_statout, gensym("port"), 1, ap); return; @@ -637,26 +622,25 @@ static void tcpserver_port(t_tcpserver*x, t_floatarg fportno) /* streaming protocol */ if (listen(sockfd, 5) < 0) { - sys_sockerror("tcpserver: listen"); + iemnet_log(x, IEMNET_ERROR, "unable to listen on TCP/IP socket"); + sys_sockerror("listen"); iemnet__closesocket(sockfd); sockfd = -1; outlet_anything(x->x_statout, gensym("port"), 1, ap); return; } else { - sys_addpollfn(sockfd, (t_fdpollfn)tcpserver_connectpoll, - x); // wait for new connections + /* wait for new connections */ + sys_addpollfn(sockfd, (t_fdpollfn)tcpserver_connectpoll, x); } x->x_connectsocket = sockfd; x->x_port = portno; - // find out which port is actually used (useful when assigning "0") if(!getsockname(sockfd, (struct sockaddr *)&server, &serversize)) { x->x_port=ntohs(server.sin_port); } - SETFLOAT(ap, x->x_port); outlet_anything(x->x_statout, gensym("port"), 1, ap); } @@ -693,8 +677,6 @@ static void *tcpserver_new(t_floatarg fportno) } x->x_defaulttarget=0; - - x->x_floatlist=iemnet__floatlist_create(1024); tcpserver_port(x, fportno); @@ -753,7 +735,6 @@ IEMNET_EXTERN void tcpserver_setup(void) gensym("targetsocket"), A_DEFFLOAT, 0); class_addlist (tcpserver_class, (t_method)tcpserver_defaultsend); - class_addmethod(tcpserver_class, (t_method)tcpserver_serialize, gensym("serialize"), A_FLOAT, 0); @@ -767,5 +748,4 @@ IEMNET_EXTERN void tcpserver_setup(void) IEMNET_INITIALIZER(tcpserver_setup); - /* end of tcpserver.c */ diff --git a/udpreceive.c b/udpreceive.c index 5fc092e..7aaca12 100644 --- a/udpreceive.c +++ b/udpreceive.c @@ -1,5 +1,5 @@ /* udpreceive.c - * copyright (c) 2010 IOhannes m zmölnig, IEM + * copyright © 2010-2015 IOhannes m zmölnig, IEM * copyright (c) 2006-2010 Martin Peach * copyright (c) Miller Puckette */ @@ -57,7 +57,7 @@ static void udpreceive_read_callback(void*y, t_iemnet_chunk*c) outlet_list(x->x_msgout, gensym("list"), x->x_floatlist->argc, x->x_floatlist->argv); } else { - post("[%s] nothing received", objName); + iemnet_log(x, IEMNET_VERBOSE, "nothing received"); } } @@ -76,13 +76,15 @@ static int udpreceive_setport(t_udpreceive*x, unsigned short portno) /* cleanup any open ports */ if(sockfd>=0) { iemnet__receiver_destroy(x->x_receiver, 0); + iemnet__closesocket(sockfd); x->x_connectsocket=-1; x->x_port=-1; } sockfd = socket(AF_INET, SOCK_DGRAM, 0); if(sockfd<0) { - pd_error(x, "[%s]: unable to create socket", objName); + iemnet_log(x, IEMNET_ERROR, "unable to create socket"); + sys_sockerror("socket"); return 0; } @@ -93,7 +95,8 @@ static int udpreceive_setport(t_udpreceive*x, unsigned short portno) if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (void *)&intarg, sizeof(intarg)) < 0) { - pd_error(x, "[%s]: setsockopt (SO_REUSEADDR) failed", objName); + iemnet_log(x, IEMNET_ERROR, "unable to enable address re-using"); + sys_sockerror("setsockopt:SO_REUSEADDR"); } } #endif /* SO_REUSEADDR */ @@ -103,7 +106,8 @@ static int udpreceive_setport(t_udpreceive*x, unsigned short portno) if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEPORT, (void *)&intarg, sizeof(intarg)) < 0) { - pd_error(x, "[%s]: setsockopt (SO_REUSEPORT) failed", objName); + iemnet_log(x, IEMNET_ERROR, "unable to enable port re-using"); + sys_sockerror("setsockopt:SO_REUSEPORT"); } } #endif /* SO_REUSEPORT */ @@ -114,7 +118,8 @@ static int udpreceive_setport(t_udpreceive*x, unsigned short portno) /* name the socket */ if (bind(sockfd, (struct sockaddr *)&server, serversize) < 0) { - sys_sockerror("[udpreceive] bind failed"); + iemnet_log(x, IEMNET_ERROR, "unable to bind to socket"); + sys_sockerror("bind"); iemnet__closesocket(sockfd); sockfd = -1; return 0; @@ -141,7 +146,7 @@ static void udpreceive_port(t_udpreceive*x, t_symbol*s, int argc, t_atom ap[1]; if(argc) { if(argc>1 || A_FLOAT != argv->a_type) { - pd_error(x, "[%s] usage: port []", objName); + iemnet_log(x, IEMNET_ERROR, "usage: %s []", s->s_name); return; } SETFLOAT(ap, -1); @@ -166,7 +171,7 @@ static void udpreceive_optionI(t_udpreceive*x, t_symbol*s, int argc, } if(!reuse) { - pd_error(x, "[%s]: unknown option '%s'", objName, s->s_name); + iemnet_log(x, IEMNET_ERROR, "unknown option '%s'", s->s_name); return; } if(argc) { @@ -174,7 +179,7 @@ static void udpreceive_optionI(t_udpreceive*x, t_symbol*s, int argc, *reuse=atom_getint(argv); return; } else { - pd_error(x, "[%s] usage: %s []", objName, s->s_name); + iemnet_log(x, IEMNET_ERROR, "usage: %s []", s->s_name); return; } } else { @@ -208,8 +213,14 @@ static void *udpreceive_new(t_floatarg fportno) static void udpreceive_free(t_udpreceive *x) { - iemnet__receiver_destroy(x->x_receiver, 0); - x->x_connectsocket=0; + if(x->x_receiver) { + iemnet__receiver_destroy(x->x_receiver, 0); + } + x->x_receiver=NULL; + if(x->x_connectsocket >= 0) { + iemnet__closesocket(x->x_connectsocket); + } + x->x_connectsocket=-1; outlet_free(x->x_msgout); outlet_free(x->x_addrout); diff --git a/udpsend.c b/udpsend.c index 620f7c0..3451a41 100644 --- a/udpsend.c +++ b/udpsend.c @@ -1,5 +1,5 @@ /* udpsend.c - * copyright (c) 2010 IOhannes m zmölnig, IEM + * copyright © 2010-2015 IOhannes m zmölnig, IEM * copyright (c) 2006-2010 Martin Peach * copyright (c) Miller Puckette */ @@ -34,79 +34,67 @@ static t_class *udpsend_class; typedef struct _udpsend { t_object x_obj; t_iemnet_sender*x_sender; + int x_fd; } t_udpsend; static void udpsend_connect(t_udpsend *x, t_symbol *hostname, t_floatarg fportno) { struct sockaddr_in server; + struct hostent *hp = NULL; int sockfd; int portno = fportno; int broadcast = 1;/* nonzero is true */ memset(&server, 0, sizeof(server)); if (x->x_sender) { - error("[%s] already connected", objName); + iemnet_log(x, IEMNET_ERROR, "already connected"); return; } + /* connect socket using hostname provided in command line */ + server.sin_family = AF_INET; + + hp = gethostbyname(hostname->s_name); + if (hp == 0) { + iemnet_log(x, IEMNET_ERROR, "bad host '%s'?", hostname->s_name); + return; + } + memcpy((char *)&server.sin_addr, (char *)hp->h_addr, hp->h_length); + + /* assign client port number */ + server.sin_port = htons((u_short)portno); + + DEBUG("connecting to port %d", portno); + + /* create a socket */ sockfd = socket(AF_INET, SOCK_DGRAM, 0); DEBUG("send socket %d\n", sockfd); if (sockfd < 0) { - sys_sockerror("[udpsend] socket"); + iemnet_log(x, IEMNET_ERROR, "unable to create datagram socket"); + sys_sockerror("socket"); return; } - /* Based on zmoelnig's patch 2221504: - Enable sending of broadcast messages (if hostname is a broadcast address)*/ + /* Enable sending of broadcast messages (if hostname is a broadcast address)*/ #ifdef SO_BROADCAST if( 0 != setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, (const void *)&broadcast, sizeof(broadcast))) { - error("[%s] couldn't switch to broadcast mode", objName); + iemnet_log(x, IEMNET_ERROR, "unable to switch to broadcast mode"); + sys_sockerror("setsockopt:SO_BROADCAST"); } #endif /* SO_BROADCAST */ - /* connect socket using hostname provided in command line */ - server.sin_family = AF_INET; - - do { -#if 0 - struct addrinfo * addr=NULL; - if(getaddrinfo(hostname->s_name, NULL, NULL, &addr)) { - error("[%s] bad host '%s'?", objName, hostname->s_name); - return; - } else { - struct addrinfo * res; - for (res = addr; res != NULL; res = res->ai_next) { - struct sockaddr_in *sa = (struct sockaddr_in *) res->ai_addr; - int len = res->ai_addrlen; - // memcpy((char *)&server.sin_addr, (char *)res->ai_addr, hp->h_length); - // LATER check how to do that... - } - } - freeaddrinfo(addr); -#else - struct hostent *hp = gethostbyname(hostname->s_name); - if (hp == 0) { - error("[%s] bad host '%s'?", objName, hostname->s_name); - return; - } - memcpy((char *)&server.sin_addr, (char *)hp->h_addr, hp->h_length); -#endif - } while(0); - - /* assign client port number */ - server.sin_port = htons((u_short)portno); - - DEBUG("connecting to port %d", portno); /* try to connect. */ if (connect(sockfd, (struct sockaddr *) &server, sizeof (server)) < 0) { - sys_sockerror("[udpsend] connecting stream socket"); + iemnet_log(x, IEMNET_ERROR, "unable to connect to socket:%d", sockfd); + sys_sockerror("connect"); iemnet__closesocket(sockfd); return; } x->x_sender=iemnet__sender_create(sockfd, NULL, NULL, 0); + x->x_fd = sockfd; outlet_float(x->x_obj.ob_outlet, 1); } @@ -114,7 +102,11 @@ static void udpsend_disconnect(t_udpsend *x) { if(x->x_sender) { iemnet__sender_destroy(x->x_sender, 0); - x->x_sender=NULL; + } + x->x_sender=NULL; + if(x->x_fd >= 0) { + iemnet__closesocket(x->x_fd); + x->x_fd=-1; outlet_float(x->x_obj.ob_outlet, 0); } } @@ -126,7 +118,7 @@ static void udpsend_send(t_udpsend *x, t_symbol *s, int argc, t_atom *argv) iemnet__sender_send(x->x_sender, chunk); iemnet__chunk_destroy(chunk); } else { - error("[%s]: not connected", objName); + iemnet_log(x, IEMNET_ERROR, "not connected"); } } @@ -166,4 +158,3 @@ IEMNET_EXTERN void udpsend_setup(void) IEMNET_INITIALIZER(udpsend_setup); /* end udpsend.c*/ - diff --git a/udpserver.c b/udpserver.c index df4b389..8ecfe90 100644 --- a/udpserver.c +++ b/udpserver.c @@ -2,7 +2,7 @@ * * listens on a UDP-socket for bi-directional communication * - * copyright (c) 2010 IOhannes m zmölnig, IEM + * copyright © 2010-2015 IOhannes m zmölnig, IEM * copyright (c) 2006-2010 Martin Peach * copyright (c) 2004 Olaf Matthes */ @@ -66,8 +66,8 @@ typedef struct _udpserver { unsigned char x_accept; /* whether we accept new connections or not */ - int - x_defaulttarget; /* the default connection to send to; 0=broadcast; >0 use this client; <0 exclude this client */ + /* the default connection to send to; 0=broadcast; >0 use this client; <0 exclude this client */ + int x_defaulttarget; t_iemnet_receiver *x_receiver; t_iemnet_floatlist *x_floatlist; @@ -79,7 +79,7 @@ static t_udpserver_sender *udpserver_sender_new(t_udpserver *owner, t_udpserver_sender *x = (t_udpserver_sender *)malloc(sizeof( t_udpserver_sender)); if(NULL==x) { - error("%s_sender: unable to allocate %d bytes", objName, (int)sizeof(*x)); + iemnet_log(owner, IEMNET_FATAL, "unable to allocate %d bytes to create sender", (int)sizeof(*x)); return NULL; } else { int sockfd = owner->x_connectsocket; @@ -104,7 +104,6 @@ static void udpserver_sender_free(t_udpserver_sender *x) x->sr_owner=NULL; x->sr_sender=NULL; - x->sr_fd=-1; free(x); @@ -112,11 +111,12 @@ static void udpserver_sender_free(t_udpserver_sender *x) if(sender) { iemnet__sender_destroy(sender, 0); } - - iemnet__closesocket(sockfd); + if(sockfd>=0) { + iemnet__closesocket(sockfd); + } } /* coverity[pass_freed_arg]: this is merely for debugging printout */ - DEBUG("freeed %x", x); + DEBUG("freed %x", x); } static t_udpserver_sender* udpserver_sender_copy(t_udpserver_sender*x) @@ -142,13 +142,14 @@ static int udpserver_socket2index(t_udpserver*x, int sockfd) static int udpserver_fixindex(t_udpserver*x, int client) { if(x->x_nconnections <= 0) { - pd_error(x, "[%s]: no clients connected", objName); + iemnet_log(x, IEMNET_ERROR, "no clients connected"); return -1; } if (!((client > 0) && (client <= x->x_nconnections))) { - pd_error(x, "[%s] client %d out of range [1..%d]", objName, client, - (int)(x->x_nconnections)); + iemnet_log(x, IEMNET_ERROR, + "client:%d out of range [1..%d]", + client, (int)(x->x_nconnections)); return -1; } return (client-1); @@ -248,7 +249,6 @@ static void udpserver_sender_remove(t_udpserver*x, unsigned int id) } } - /* ---------------- udpserver info ---------------------------- */ static void udpserver_info_client(t_udpserver *x, int client) { @@ -292,12 +292,11 @@ static void udpserver_info(t_udpserver *x) static t_atom output_atom[4]; int sockfd=x->x_connectsocket; - int port=x->x_port; if(sockfd<0) { // no open port - error("[%s] no valid sock", objName); + iemnet_log(x, IEMNET_ERROR, "no open socket"); } if(x->x_port<=0) { @@ -309,7 +308,8 @@ static void udpserver_info(t_udpserver *x) x->x_port=ntohs(server.sin_port); port=x->x_port; } else { - error("[%s] gesockname failed for %d", objName, sockfd); + iemnet_log(x, IEMNET_ERROR, "getsockname failed for socket:%d", sockfd); + sys_sockerror("getsockname"); } } @@ -361,7 +361,6 @@ static void udpserver_send_bytes(t_udpserver*x, unsigned int client, } - /* broadcasts a message to all connected clients but the given one */ static void udpserver_send_butclient(t_udpserver *x, unsigned int but, int argc, t_atom *argv) @@ -388,8 +387,6 @@ static void udpserver_send_toclient(t_udpserver *x, unsigned int client, iemnet__chunk_destroy(chunk); } - - /* send message to client using client number note that the client numbers might change in case a client disconnects! */ /* clients start at 1 but our index starts at 0 */ @@ -458,8 +455,9 @@ static void udpserver_defaultsend(t_udpserver *x, t_symbol *s, int argc, if(sockfd>0) { client=udpserver_socket2index(x, sockfd); if(client<0) { - pd_error(x, "[%s] illegal socket %d, switching to broadcast mode", objName, - sockfd); + iemnet_log(x, IEMNET_ERROR, + "invalid socket %d, switching to broadcast mode", + sockfd); x->x_defaulttarget=0; } else { udpserver_send_toclient(x, client, argc, argv); @@ -468,8 +466,9 @@ static void udpserver_defaultsend(t_udpserver *x, t_symbol *s, int argc, } else if(sockfd<0) { client=udpserver_socket2index(x, -sockfd); if(client<0) { - pd_error(x, "[%s] illegal !socket %d, switching to broadcast mode", - objName, sockfd); + iemnet_log(x, IEMNET_ERROR, + "invalid excluded socket %d, switching to broadcast mode", + -sockfd); x->x_defaulttarget=0; } else { udpserver_send_butclient(x, client, argc, argv); @@ -486,8 +485,9 @@ static void udpserver_defaulttarget(t_udpserver *x, t_floatarg f) int client=(rawclient<0)?(-rawclient):rawclient; if(client > x->x_nconnections) { - error("[%s] target %d out of range [0..%d]", objName, client, - (int)(x->x_nconnections)); + iemnet_log(x, IEMNET_ERROR, + "target:%d out of range [0..%d]", + client, (int)(x->x_nconnections)); return; } @@ -509,7 +509,6 @@ static void udpserver_targetsocket(t_udpserver *x, t_floatarg f) } - /* send message to client using socket number */ static void udpserver_send_socket(t_udpserver *x, t_symbol *s, int argc, t_atom *argv) @@ -522,7 +521,7 @@ static void udpserver_send_socket(t_udpserver *x, t_symbol *s, int argc, return; } } else { - pd_error(x, "%s_send: no socket specified", objName); + iemnet_log(x, IEMNET_ERROR, "no socket specified"); return; } @@ -531,11 +530,11 @@ static void udpserver_send_socket(t_udpserver *x, t_symbol *s, int argc, int sockfd=atom_getint(argv); client = udpserver_socket2index(x, sockfd); if(client < 0) { - error("[%s]: no connection on socket %d", objName, sockfd); + iemnet_log(x, IEMNET_ERROR, "no connection on socket:%d", sockfd); return; } } else { - error("[%s]: no socket specified", objName); + iemnet_log(x, IEMNET_ERROR, "no socket specified"); return; } @@ -570,7 +569,6 @@ static void udpserver_disconnect(t_udpserver *x, unsigned int client) outlet_float(x->x_connectout, conns); } - /* disconnect a client by number */ static void udpserver_disconnect_client(t_udpserver *x, t_floatarg fclient) { @@ -582,7 +580,6 @@ static void udpserver_disconnect_client(t_udpserver *x, t_floatarg fclient) udpserver_disconnect(x, client); } - /* disconnect a client by socket */ static void udpserver_disconnect_socket(t_udpserver *x, t_floatarg fsocket) { @@ -592,8 +589,6 @@ static void udpserver_disconnect_socket(t_udpserver *x, t_floatarg fsocket) } } - - /* disconnect a client by socket */ static void udpserver_disconnect_all(t_udpserver *x) { @@ -609,7 +604,6 @@ static void udpserver_accept(t_udpserver *x, t_float f) x->x_accept=(unsigned char)f; } - /* ---------------- main udpserver (receive) stuff --------------------- */ static void udpserver_receive_callback(void *y, t_iemnet_chunk*c) { @@ -638,7 +632,7 @@ static void udpserver_receive_callback(void *y, t_iemnet_chunk*c) } } else { // disconnection never happens with a connectionless protocol like UDP - pd_error(x, "[%s] received disconnection event", objName); + iemnet_log(x, IEMNET_ERROR, "received disonnection event"); } } @@ -704,7 +698,8 @@ static void udpserver_port(t_udpserver*x, t_floatarg fportno) sockfd = socket(AF_INET, SOCK_DGRAM, 0); if(sockfd<0) { - sys_sockerror("[udpserver]: cannot create UDP socket"); + iemnet_log(x, IEMNET_ERROR, "unable to create socket"); + sys_sockerror("socket"); return; } @@ -717,7 +712,8 @@ static void udpserver_port(t_udpserver*x, t_floatarg fportno) server.sin_port = htons((u_short)portno); /* name the socket */ if (bind(sockfd, (struct sockaddr *)&server, serversize) < 0) { - sys_sockerror("udpserver: bind"); + iemnet_log(x, IEMNET_ERROR, "unable to bind to socket"); + sys_sockerror("bind"); iemnet__closesocket(sockfd); outlet_anything(x->x_statout, gensym("port"), 1, ap); return; @@ -727,17 +723,14 @@ static void udpserver_port(t_udpserver*x, t_floatarg fportno) x, udpserver_receive_callback, 0); - x->x_connectsocket = sockfd; x->x_port = portno; - // find out which port is actually used (useful when assigning "0") if(!getsockname(sockfd, (struct sockaddr *)&server, &serversize)) { x->x_port=ntohs(server.sin_port); } - SETFLOAT(ap, x->x_port); outlet_anything(x->x_statout, gensym("port"), 1, ap); } @@ -754,8 +747,8 @@ static void *udpserver_new(t_floatarg fportno) gensym("float")); /* 2nd outlet for number of connected clients */ x->x_sockout = outlet_new(&x->x_obj, gensym("float")); x->x_addrout = outlet_new(&x->x_obj, gensym("list" )); - x->x_statout = outlet_new(&x->x_obj, - 0);/* 5th outlet for everything else */ + /* 5th outlet for everything else */ + x->x_statout = outlet_new(&x->x_obj, 0); x->x_connectsocket = -1; x->x_port = -1; diff --git a/udpsndrcv-help.pd b/udpsndrcv-help.pd new file mode 100644 index 0000000..e65f129 --- /dev/null +++ b/udpsndrcv-help.pd @@ -0,0 +1,59 @@ +#N canvas 247 75 632 526 10; +#X obj 72 255 udpsndrcv; +#X msg 72 148 connect localhost 12345 54321; +#X obj 382 255 udpsndrcv; +#X obj 72 360 print A:connected?; +#X obj 102 329 print A:data; +#X obj 132 300 print A:status; +#X obj 442 300 print B:status; +#X obj 412 329 print B:data; +#X obj 382 357 print B:connected?; +#X msg 86 171 send 10 20 30 40; +#X msg 91 196 disconnect; +#X msg 114 224 status; +#X msg 401 196 disconnect; +#X msg 424 224 status; +#X msg 382 148 connect localhost 54321 12345; +#X msg 396 171 send 50 40 30 20 10; +#X text 80 26 [udpsndrcv] bi-directional communication; +#X text 74 59 this is an abstraction around [udpclient] for compatibility +with mrpeach/net's object of the same name.; +#N canvas 4 78 530 417 sending/receiving 0; +#X obj 142 275 udpsndrcv; +#X msg 161 216 disconnect; +#X msg 184 244 status; +#X msg 142 168 connect localhost 55555 55555; +#X msg 156 191 send 5 5 5; +#X obj 202 320 print C:status; +#X obj 172 349 print C:data; +#X obj 142 377 print C:connected?; +#X text 52 58 when using the same port for sending and receiving \, +you must talk with real remote host (NOT localhost).; +#X text 55 88 else you will simply be talking to yourself...; +#X text 156 146 talk to yourself.; +#X connect 0 0 7 0; +#X connect 0 1 6 0; +#X connect 0 2 5 0; +#X connect 1 0 0 0; +#X connect 2 0 0 0; +#X connect 3 0 0 0; +#X connect 4 0 0 0; +#X restore 172 492 pd sending/receiving on the same port; +#X text 86 394 send to port:12345; +#X text 72 409 listen on port:54321; +#X text 396 394 send to port:54321; +#X text 382 409 listen on port:12345; +#X connect 0 0 3 0; +#X connect 0 1 4 0; +#X connect 0 2 5 0; +#X connect 1 0 0 0; +#X connect 2 0 8 0; +#X connect 2 1 7 0; +#X connect 2 2 6 0; +#X connect 9 0 0 0; +#X connect 10 0 0 0; +#X connect 11 0 0 0; +#X connect 12 0 2 0; +#X connect 13 0 2 0; +#X connect 14 0 2 0; +#X connect 15 0 2 0; diff --git a/udpsndrcv.pd b/udpsndrcv.pd new file mode 100644 index 0000000..119ed0d --- /dev/null +++ b/udpsndrcv.pd @@ -0,0 +1,71 @@ +#N canvas 512 227 613 300 10; +#X obj 60 73 inlet; +#X obj 116 174 udpclient; +#X obj 43 249 outlet conn?; +#X obj 145 258 outlet data; +#X obj 260 270 outlet status; +#X obj 60 105 t a a; +#X obj 60 127 route status; +#X obj 216 65 route connect disconnect; +#X obj 116 196 t l l; +#N canvas 5 49 450 300 received 0; +#X obj 101 65 inlet; +#X obj 101 87 list length; +#X obj 101 131 delay 0; +#X obj 190 172 +; +#X obj 190 194 t f f; +#X obj 130 223 f; +#X obj 130 195 t b f; +#X msg 101 153 0; +#X obj 101 109 t b f f; +#X obj 130 275 outlet received; +#X msg 130 245 received \$1; +#X obj 350 172 +; +#X obj 350 194 t f f; +#X obj 290 223 f; +#X obj 236 54 inlet; +#X msg 290 245 total \$1; +#X obj 236 76 route bang reset; +#X msg 290 112 0; +#X connect 0 0 1 0; +#X connect 1 0 8 0; +#X connect 2 0 7 0; +#X connect 3 0 4 0; +#X connect 4 0 5 1; +#X connect 4 1 3 1; +#X connect 5 0 10 0; +#X connect 6 0 5 0; +#X connect 6 1 3 1; +#X connect 7 0 6 0; +#X connect 8 0 2 0; +#X connect 8 1 3 0; +#X connect 8 2 11 0; +#X connect 10 0 9 0; +#X connect 11 0 12 0; +#X connect 12 0 13 1; +#X connect 12 1 11 1; +#X connect 13 0 15 0; +#X connect 14 0 16 0; +#X connect 15 0 9 0; +#X connect 16 0 13 0; +#X connect 16 1 17 0; +#X connect 17 0 12 0; +#X restore 260 241 pd received; +#X obj 60 149 t b; +#X obj 216 90 t b; +#X msg 216 112 reset; +#X connect 0 0 5 0; +#X connect 1 0 8 0; +#X connect 1 2 2 0; +#X connect 5 0 6 0; +#X connect 5 1 7 0; +#X connect 6 0 10 0; +#X connect 6 1 1 0; +#X connect 7 0 11 0; +#X connect 7 1 11 0; +#X connect 8 0 3 0; +#X connect 8 1 9 0; +#X connect 9 0 4 0; +#X connect 10 0 9 1; +#X connect 11 0 12 0; +#X connect 12 0 9 1; -- cgit v1.2.1