aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIOhannes m zmölnig <zmoelnig@users.sourceforge.net>2015-09-01 14:30:54 +0000
committerIOhannes m zmölnig <zmoelnig@users.sourceforge.net>2015-09-01 14:30:54 +0000
commite6f799e41d7910e1388c68630c49bf3141cb8d9c (patch)
tree442af8d11ad2ca606f0622bf30a88db4e8fa5541
parentf628926f7ff2d494667bc14bc5d0cbcba02de5db (diff)
sync with git
svn path=/trunk/externals/iem/iemnet/; revision=17545
-rw-r--r--ChangeLog13
-rw-r--r--Makefile57
-rw-r--r--iemnet-meta.pd2
-rw-r--r--iemnet.c54
-rw-r--r--iemnet.h9
-rw-r--r--iemnet_data.c2
-rw-r--r--iemnet_receiver.c2
-rw-r--r--iemnet_sender.c6
-rw-r--r--tcpclient.c19
-rw-r--r--tcpreceive.c44
-rw-r--r--tcpsend.c30
-rw-r--r--tcpserver.c104
-rw-r--r--udpreceive.c33
-rw-r--r--udpsend.c77
-rw-r--r--udpserver.c75
-rw-r--r--udpsndrcv-help.pd59
-rw-r--r--udpsndrcv.pd71
17 files changed, 410 insertions, 247 deletions
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 <zmoelnig@iem.at>;
#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 <stdarg.h>
+#include <string.h>
+#include <m_imp.h>
+
+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 <netinet/tcp.h>
#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 [<portnum>]", objName);
+ iemnet_log(x, IEMNET_ERROR, "usage: %s [<portnum>]", 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 [<val>]", objName, s->s_name);
+ iemnet_log(x, IEMNET_ERROR, "usage: %s [<val>]", 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;