aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Peach <mrpeach@users.sourceforge.net>2014-02-13 22:00:27 +0000
committerMartin Peach <mrpeach@users.sourceforge.net>2014-02-13 22:00:27 +0000
commitb6bd4fb4475da960744ff6b169f89dbb859b0d9c (patch)
tree67f7a9a73a6aa80c5abf345e5a938407d8de80c7
parent02cce30ccf8b11a94f3c262d3ad456c3f446fd91 (diff)
Possibly fixed some crashing when freeing resources, by checking for NULL before freeing.
Added a verbosity message to control printout to console. Default is 0, or no output except errors. Fixed a bug with the [client n( message and non-existent client number. --This line, and those below, will be ignored- M tcpserver.c M tcpserver-help.pd svn path=/trunk/externals/mrpeach/; revision=17265
-rw-r--r--net/tcpserver-help.pd18
-rw-r--r--net/tcpserver.c262
2 files changed, 156 insertions, 124 deletions
diff --git a/net/tcpserver-help.pd b/net/tcpserver-help.pd
index 13defdc..9cafbea 100644
--- a/net/tcpserver-help.pd
+++ b/net/tcpserver-help.pd
@@ -1,4 +1,4 @@
-#N canvas 322 104 1272 779 12;
+#N canvas 4 103 1272 816 12;
#X msg 39 -10 print;
#X floatatom 404 376 5 0 0 0 - - -;
#X floatatom 428 426 5 0 0 0 - - -;
@@ -53,7 +53,7 @@
#X msg -41 -90 disconnectsocket \$1;
#X msg -84 -133 disconnectclient \$1;
#X obj 647 257 s toserver;
-#X obj 381 324 r toserver;
+#X obj 376 327 r toserver;
#X floatatom 143 -172 5 0 0 0 - - -;
#X obj 121 -153 f;
#X obj 121 -172 bng 15 250 50 0 empty empty empty 17 7 0 10 -258699
@@ -119,7 +119,7 @@ hang pd!;
#X text -143 233 If sending too many messages blocks the system \,
tcpserver will stop sending until it receives an unblock message;
#X obj 712 419 print blocked;
-#N canvas 529 82 494 344 META 0;
+#N canvas 530 81 494 344 META 0;
#X text 12 225 HELP_PATCH_AUTHORS "pd meta" information added by Jonathan
Wilkes for Pd version 0.42.;
#X text 12 205 AUTHOR Martin Peach;
@@ -134,10 +134,14 @@ send print broadcast dump clientbuf unblock;
#X text 12 165 OUTLET_3 list;
#X text 12 185 OUTLET_4 sent client blocked;
#X restore 899 458 pd META;
-#X msg 335 286 port 12345;
-#X text 417 285 change listening port (only if no connections are active)
+#X msg 354 305 port 12345;
+#X text 436 304 change listening port (only if no connections are active)
;
-#X text -9 536 2013/05/20 Martin Peach;
+#X msg 332 283 verbosity \$1;
+#X obj 332 263 hradio 15 1 0 4 empty empty empty 0 -8 0 10 -1 -4034
+-1 0;
+#X text 425 281 set verbosity level;
+#X text -9 536 2014/02/13 Martin Peach;
#X connect 0 0 60 0;
#X connect 3 0 4 0;
#X connect 3 1 5 0;
@@ -201,3 +205,5 @@ send print broadcast dump clientbuf unblock;
#X connect 96 2 98 0;
#X connect 96 3 67 0;
#X connect 100 0 60 0;
+#X connect 102 0 60 0;
+#X connect 103 0 102 0;
diff --git a/net/tcpserver.c b/net/tcpserver.c
index ca872b4..573e701 100644
--- a/net/tcpserver.c
+++ b/net/tcpserver.c
@@ -95,6 +95,7 @@ typedef struct _tcpserver_send_params
int sockfd;
char *byte_buf;
size_t length;
+ int verbosity;
} t_tcpserver_send_params;
typedef struct _tcpserver
@@ -115,6 +116,7 @@ typedef struct _tcpserver
t_int x_port;
t_int x_nconnections;
t_int x_blocked;
+ t_int x_verbosity;
t_atom x_msgoutbuf[MAX_UDP_RECEIVE];
char x_msginbuf[MAX_UDP_RECEIVE];
} t_tcpserver;
@@ -146,6 +148,7 @@ static void tcpserver_buf_size(t_tcpserver *x, t_symbol *s, int argc, t_atom *ar
static void tcpserver_disconnect(t_tcpserver *x);
static void tcpserver_client_disconnect(t_tcpserver *x, t_floatarg fclient);
static void tcpserver_socket_disconnect(t_tcpserver *x, t_floatarg fsocket);
+static void tcpserver_verbosity(t_tcpserver *x, t_floatarg verbosity_level);
static void tcpserver_broadcast(t_tcpserver *x, t_symbol *s, int argc, t_atom *argv);
static void tcpserver_notify(t_tcpserver *x);
static void tcpserver_connectpoll(t_tcpserver *x);
@@ -156,22 +159,28 @@ static void tcpserver_port(t_tcpserver *x, t_floatarg fportno);
static void tcpserver_free(t_tcpserver *x);
void tcpserver_setup(void);
static void tcpserver_dump(t_tcpserver *x, t_float dump);
-static void tcpserver_hexdump(unsigned char *buf, long len);
+static void tcpserver_hexdump(unsigned char *buf, long len, int verbosity);
+
+
+static void tcpserver_verbosity(t_tcpserver *x, t_floatarg verbosity_level)
+{
+ x->x_verbosity = verbosity_level;
+ if (x->x_verbosity > 0) post("tcpserver_verbosity now %d", x->x_verbosity);
+}
static void tcpserver_dump(t_tcpserver *x, t_float dump)
{
x->x_dump = (dump == 0)?0:1;
}
-static void tcpserver_hexdump(unsigned char *buf, long len)
+static void tcpserver_hexdump(unsigned char *buf, long len, int verbosity)
{
#define BYTES_PER_LINE 16
char hexStr[(3*BYTES_PER_LINE)+1];
char ascStr[BYTES_PER_LINE+1];
long i, j, k = 0L;
-#ifdef DEBUG
- post("tcpserver_hexdump %d", len);
-#endif
+
+ if (verbosity > 0) post("tcpserver_hexdump of %d bytes", len);
while (k < len)
{
for (i = j = 0; i < BYTES_PER_LINE; ++i, ++k, j+=3)
@@ -197,7 +206,7 @@ static t_tcpserver_socketreceiver *tcpserver_socketreceiver_new(void *owner, t_t
t_tcpserver_socketreceiver *x = (t_tcpserver_socketreceiver *)getbytes(sizeof(*x));
if (!x)
{
- error("%s_socketreceiver: unable to allocate %lu bytes", objName, sizeof(*x));
+ error("%s_socketreceiver: unable to allocate %zu bytes", objName, sizeof(*x));
}
else
{
@@ -229,9 +238,7 @@ static int tcpserver_socketreceiver_doread(t_tcpserver_socketreceiver *x)
unsigned char *inbuf = x->sr_inbuf;
if (intail == inhead) return (0);
-#ifdef DEBUG
- post ("%s_socketreceiver_doread: intail=%d inhead=%d", objName, intail, inhead);
-#endif
+ if (y->x_verbosity > 1) post ("%s_socketreceiver_doread: intail=%d inhead=%d", objName, intail, inhead);
for (indx = intail, i = 0; indx != inhead; indx = (indx+1)&(INBUFSIZE-1), ++i)
{
@@ -239,7 +246,7 @@ static int tcpserver_socketreceiver_doread(t_tcpserver_socketreceiver *x)
y->x_msgoutbuf[i].a_w.w_float = (float)c;
}
- if (y->x_dump)tcpserver_hexdump(&inbuf[intail], i);
+ if (y->x_dump)tcpserver_hexdump(&inbuf[intail], i, y->x_verbosity);
if (i > 1) outlet_list(y->x_msgout, &s_list, i, y->x_msgoutbuf);
else outlet_float(y->x_msgout, y->x_msgoutbuf[0].a_w.w_float);
@@ -260,7 +267,7 @@ static void tcpserver_socketreceiver_read(t_tcpserver_socketreceiver *x, int fd)
/* the input buffer might be full. If so, drop the whole thing */
if (readto == x->sr_inhead)
{
- post("%s: dropped message", objName);
+ if (y->x_verbosity > 0) post("%s: dropped message", objName);
x->sr_inhead = x->sr_intail = 0;
readto = INBUFSIZE;
}
@@ -277,16 +284,14 @@ static void tcpserver_socketreceiver_read(t_tcpserver_socketreceiver *x, int fd)
}
else if (ret == 0)
{
- post("%s: connection closed on socket %d", objName, fd);
+ if (y->x_verbosity > 0) post("%s: connection closed on socket %d", objName, fd);
if (x->sr_notifier) (*x->sr_notifier)(x->sr_owner);
sys_rmpollfn(fd);
sys_closesocket(fd);
}
else
{
-#ifdef DEBUG
- post ("%s_socketreceiver_read: ret = %d", objName, ret);
-#endif
+ if (y->x_verbosity > 1) post ("%s_socketreceiver_read: ret = %d", objName, ret);
x->sr_inhead += ret;
if (x->sr_inhead >= INBUFSIZE) x->sr_inhead = 0;
/* output client's IP and socket no. */
@@ -294,7 +299,6 @@ static void tcpserver_socketreceiver_read(t_tcpserver_socketreceiver *x, int fd)
{
if(y->x_sr[i]->sr_fd == y->x_sock_fd)
{
-// outlet_symbol(x->x_connectionip, x->x_sr[i].sr_host);
/* find sender's ip address and output it */
y->x_addrbytes[0].a_w.w_float = (y->x_sr[i]->sr_addr & 0xFF000000)>>24;
y->x_addrbytes[1].a_w.w_float = (y->x_sr[i]->sr_addr & 0x0FF0000)>>16;
@@ -312,9 +316,17 @@ static void tcpserver_socketreceiver_read(t_tcpserver_socketreceiver *x, int fd)
static void tcpserver_socketreceiver_free(t_tcpserver_socketreceiver *x)
{
+ t_tcpserver *y = x->sr_owner;
+
+ if (y->x_verbosity > 1) post("tcpserver_socketreceiver_free x=%p", x);
if (x != NULL)
{
- free(x->sr_inbuf);
+ if (NULL != x->sr_inbuf)
+ {
+ if (y->x_verbosity > 1) post("tcpserver_socketreceiver_free freeing x->sr_inbuf %p", x->sr_inbuf);
+ free(x->sr_inbuf);
+ x->sr_inbuf = NULL;
+ }
freebytes(x, sizeof(*x));
}
}
@@ -335,7 +347,7 @@ static void tcpserver_send_bytes(int client, t_tcpserver *x, int argc, t_atom *a
t_atom output_atom[3];
t_tcpserver_send_params *ttsp;
pthread_t sender_thread;
- pthread_attr_t sender_attr;
+ pthread_attr_t sender_attr = {{0}};
int sender_thread_result;
/* process & send data */
@@ -360,9 +372,7 @@ static void tcpserver_send_bytes(int client, t_tcpserver *x, int argc, t_atom *a
f = argv[i].a_w.w_float;
d = (int)f;
e = f - d;
-#ifdef DEBUG
- post("%s: argv[%d]: float:%f int:%d delta:%f", objName, i, f, d, e);
-#endif
+ if (x->x_verbosity > 2) post("%s: argv[%d]: float:%f int:%d delta:%f", objName, i, f, d, e);
if (e != 0)
{
error("%s: item %d (%f) is not an integer", objName, i, f);
@@ -374,9 +384,7 @@ static void tcpserver_send_bytes(int client, t_tcpserver *x, int argc, t_atom *a
goto failed;
}
c = (unsigned char)d; /* make sure it doesn't become negative; this only matters for post() */
-#ifdef DEBUG
- post("%s: argv[%d]: %d", objName, i, c);
-#endif
+ if (x->x_verbosity > 2) post("%s: argv[%d]: %d", objName, i, c);
byte_buf[j++] = c;
if (j >= MAX_UDP_RECEIVE)
{ /* if the argument list is longer than our buffer, send the buffer whenever it's full */
@@ -390,18 +398,23 @@ static void tcpserver_send_bytes(int client, t_tcpserver *x, int argc, t_atom *a
ttsp = (t_tcpserver_send_params *)getbytes(sizeof(t_tcpserver_send_params));
if (ttsp == NULL)
{
- error("%s: unable to allocate %lu bytes for t_tcpserver_send_params", objName, sizeof(t_tcpserver_send_params));
+ error("%s: unable to allocate %zu bytes for t_tcpserver_send_params", objName, sizeof(t_tcpserver_send_params));
goto failed;
}
ttsp->client = client;
ttsp->sockfd = sockfd;
ttsp->byte_buf = byte_buf;
ttsp->length = j;
+ ttsp->verbosity = x->x_verbosity;
if (0 != (sender_thread_result = pthread_create(&sender_thread, &sender_attr, tcpserver_send_buf_thread, (void *)ttsp)))
{
++x->x_blocked;
error("%s: couldn't create sender thread (%d)", objName, sender_thread_result);
- freebytes (ttsp, sizeof (t_tcpserver_send_params));
+ if (NULL != ttsp)
+ {
+ freebytes (ttsp, sizeof (t_tcpserver_send_params));
+ ttsp = NULL;
+ }
goto failed;
}
flen += j;
@@ -412,9 +425,7 @@ static void tcpserver_send_bytes(int client, t_tcpserver *x, int argc, t_atom *a
{ /* symbols are interpreted to be file names; attempt to load the file and send it */
atom_string(&argv[i], fpath, FILENAME_MAX);
-#ifdef DEBUG
- post ("%s: fname: %s", objName, fpath);
-#endif
+ if (x->x_verbosity > 2) post ("%s: fname: %s", objName, fpath);
fptr = sys_fopen(fpath, "rb");
if (fptr == NULL)
{
@@ -422,15 +433,11 @@ static void tcpserver_send_bytes(int client, t_tcpserver *x, int argc, t_atom *a
goto failed;
}
rewind(fptr);
-#ifdef DEBUG
- post("%s: d is %d", objName, d);
-#endif
while ((d = fgetc(fptr)) != EOF)
{
+ if (x->x_verbosity > 2) post("%s: d is %d", objName, d);
byte_buf[j++] = (char)(d & 0x0FF);
-#ifdef DEBUG
- post("%s: byte_buf[%d] = %d", objName, j-1, byte_buf[j-1]);
-#endif
+ if (x->x_verbosity > 2) post("%s: byte_buf[%d] = %d", objName, j-1, byte_buf[j-1]);
if (j >= MAX_UDP_RECEIVE)
{ /* if the file is longer than our buffer, send the buffer whenever it's full */
/* this might be better than allocating huge amounts of memory */
@@ -444,18 +451,23 @@ static void tcpserver_send_bytes(int client, t_tcpserver *x, int argc, t_atom *a
ttsp = (t_tcpserver_send_params *)getbytes(sizeof(t_tcpserver_send_params));
if (ttsp == NULL)
{
- error("%s: unable to allocate %lu bytes for t_tcpserver_send_params", objName, sizeof(t_tcpserver_send_params));
+ error("%s: unable to allocate %zu bytes for t_tcpserver_send_params", objName, sizeof(t_tcpserver_send_params));
goto failed;
}
ttsp->client = client;
ttsp->sockfd = sockfd;
ttsp->byte_buf = byte_buf;
ttsp->length = j;
+ ttsp->verbosity = x->x_verbosity;
if ( 0!= (sender_thread_result = pthread_create(&sender_thread, &sender_attr, tcpserver_send_buf_thread, (void *)ttsp)))
{
++x->x_blocked;
error("%s: couldn't create sender thread (%d)", objName, sender_thread_result);
- freebytes (ttsp, sizeof (t_tcpserver_send_params));
+ if (NULL != ttsp)
+ {
+ freebytes (ttsp, sizeof (t_tcpserver_send_params));
+ ttsp = NULL;
+ }
goto failed;
}
flen += j;
@@ -465,7 +477,7 @@ static void tcpserver_send_bytes(int client, t_tcpserver *x, int argc, t_atom *a
flen += j;
sys_fclose(fptr);
fptr = NULL;
- post("%s: read \"%s\" length %d byte%s", objName, fpath, flen, ((d==1)?"":"s"));
+ if (x->x_verbosity > 0) post("%s: read \"%s\" length %d byte%s", objName, fpath, flen, ((d==1)?"":"s"));
}
else
{ /* arg was neither a float nor a valid file name */
@@ -486,18 +498,23 @@ static void tcpserver_send_bytes(int client, t_tcpserver *x, int argc, t_atom *a
ttsp = (t_tcpserver_send_params *)getbytes(sizeof(t_tcpserver_send_params));
if (ttsp == NULL)
{
- error("%s: unable to allocate %lu bytes for t_tcpserver_send_params", objName, sizeof(t_tcpserver_send_params));
+ error("%s: unable to allocate %zu bytes for t_tcpserver_send_params", objName, sizeof(t_tcpserver_send_params));
goto failed;
}
ttsp->client = client;
ttsp->sockfd = sockfd;
ttsp->byte_buf = byte_buf;
ttsp->length = length;
+ ttsp->verbosity = x->x_verbosity;
if ( 0!= (sender_thread_result = pthread_create(&sender_thread, &sender_attr, tcpserver_send_buf_thread, (void *)ttsp)))
{
++x->x_blocked;
error("%s: couldn't create sender thread (%d)", objName, sender_thread_result);
- freebytes (ttsp, sizeof (t_tcpserver_send_params));
+ if (NULL != ttsp)
+ {
+ freebytes (ttsp, sizeof (t_tcpserver_send_params));
+ ttsp = NULL;
+ }
goto failed;
}
flen += length;
@@ -505,6 +522,11 @@ static void tcpserver_send_bytes(int client, t_tcpserver *x, int argc, t_atom *a
}
else post("%s: not a valid socket number (%d)", objName, sockfd);
failed:
+ if (0!= (sender_thread_result = pthread_attr_destroy(&sender_attr)))
+ {
+ error("%s_broadcast: pthread_attr_destroy failed: %d", objName, sender_thread_result);
+ }
+
SETFLOAT(&output_atom[0], client+1);
SETFLOAT(&output_atom[1], flen);
SETFLOAT(&output_atom[2], sockfd);
@@ -534,9 +556,9 @@ static void *tcpserver_send_buf_thread(void *arg)
if (result <= 0)
{
sys_sockerror("tcpserver: send");
- post("%s_send_buf: could not send data to client %d", objName, ttsp->client+1);
+ if (ttsp->verbosity > 0) post("%s_send_buf: could not send data to client %d", objName, ttsp->client+1);
}
- freebytes (arg, sizeof (t_tcpserver_send_params));
+ if (NULL != arg) freebytes (arg, sizeof (t_tcpserver_send_params));
return NULL;
}
@@ -548,7 +570,7 @@ static void tcpserver_send(t_tcpserver *x, t_symbol *s, int argc, t_atom *argv)
if(x->x_nconnections <= 0)
{
- post("%s_send: no clients connected", objName);
+ if (x->x_verbosity > 0) post("%s_send: no clients connected", objName);
return;
}
if(argc == 0) /* no socket specified: output state of all sockets */
@@ -570,13 +592,13 @@ static void tcpserver_send(t_tcpserver *x, t_symbol *s, int argc, t_atom *argv)
}
if(client == -1)
{
- post("%s_send: no connection on socket %d", objName, sockfd);
+ if (x->x_verbosity > 0) post("%s_send: no connection on socket %d", objName, sockfd);
return;
}
}
else
{
- post("%s_send: no socket specified", objName);
+ if (x->x_verbosity > 0) post("%s_send: no socket specified", objName);
return;
}
if (argc < 2) /* nothing to send: output state of this socket */
@@ -610,7 +632,7 @@ static void tcpserver_disconnect(t_tcpserver *x)
}
}
}
- post("%s__disconnect: no connection on socket %d", objName, x->x_sock_fd);
+ if (x->x_verbosity > 0) post("%s__disconnect: no connection on socket %d", objName, x->x_sock_fd);
}
/* disconnect a client by socket */
@@ -620,7 +642,7 @@ static void tcpserver_socket_disconnect(t_tcpserver *x, t_floatarg fsocket)
if(x->x_nconnections <= 0)
{
- post("%s_socket_disconnect: no clients connected", objName);
+ if (x->x_verbosity > 0) post("%s_socket_disconnect: no clients connected", objName);
return;
}
x->x_sock_fd = sock;
@@ -634,12 +656,12 @@ static void tcpserver_client_disconnect(t_tcpserver *x, t_floatarg fclient)
if(x->x_nconnections <= 0)
{
- post("%s_client_disconnect: no clients connected", objName);
+ if (x->x_verbosity > 0) post("%s_client_disconnect: no clients connected", objName);
return;
}
if (!((client > 0) && (client < MAX_CONNECT)))
{
- post("%s: client %d out of range [1..%d]", objName, client, MAX_CONNECT);
+ if (x->x_verbosity > 0) post("%s: client %d out of range [1..%d]", objName, client, MAX_CONNECT);
return;
}
--client;/* zero based index*/
@@ -657,7 +679,7 @@ static void tcpserver_client_send(t_tcpserver *x, t_symbol *s, int argc, t_atom
if(x->x_nconnections <= 0)
{
- post("%s_client_send: no clients connected", objName);
+ if (x->x_verbosity > 0) post("%s_client_send: no clients connected", objName);
return;
}
if(argc > 0)
@@ -667,12 +689,12 @@ static void tcpserver_client_send(t_tcpserver *x, t_symbol *s, int argc, t_atom
client = atom_getfloatarg(0, argc, argv);
else
{
- post("%s_client_send: specify client by number", objName);
+ if (x->x_verbosity > 0) post("%s_client_send: specify client by number", objName);
return;
}
if (!((client > 0) && (client < MAX_CONNECT)))
{
- post("%s_client_send: client %d out of range [1..%d]", objName, client, MAX_CONNECT);
+ if (x->x_verbosity > 0) post("%s_client_send: client %d out of range [1..%d]", objName, client, MAX_CONNECT);
return;
}
}
@@ -706,14 +728,19 @@ static void tcpserver_output_client_state(t_tcpserver *x, int client)
else
{
client -= 1;/* zero-based client index conflicts with 1-based user index !!! */
- /* output client parameters via status outlet */
- x->x_sr[client]->sr_fdbuf = tcpserver_get_socket_send_buf_size(x->x_sr[client]->sr_fd);
- SETFLOAT(&output_atom[0], client+1);/* user sees client 0 as 1 */
- SETFLOAT(&output_atom[1], x->x_sr[client]->sr_fd);
- output_atom[2].a_type = A_SYMBOL;
- output_atom[2].a_w.w_symbol = x->x_sr[client]->sr_host;
- SETFLOAT(&output_atom[3], x->x_sr[client]->sr_fdbuf);
- outlet_anything( x->x_status_outlet, gensym("client"), 4, output_atom);
+
+ if (client < x->x_nconnections)
+ { // only if there is such a client
+ /* output client parameters via status outlet */
+ x->x_sr[client]->sr_fdbuf = tcpserver_get_socket_send_buf_size(x->x_sr[client]->sr_fd);
+ SETFLOAT(&output_atom[0], client+1);/* user sees client 0 as 1 */
+ SETFLOAT(&output_atom[1], x->x_sr[client]->sr_fd);
+ output_atom[2].a_type = A_SYMBOL;
+ output_atom[2].a_w.w_symbol = x->x_sr[client]->sr_host;
+ SETFLOAT(&output_atom[3], x->x_sr[client]->sr_fdbuf);
+ outlet_anything( x->x_status_outlet, gensym("client"), 4, output_atom);
+ }
+ else if (x->x_verbosity > 0) post("%s: no such client (%d)", objName, client+1);
}
}
@@ -760,7 +787,7 @@ static void tcpserver_buf_size(t_tcpserver *x, t_symbol *s, int argc, t_atom *ar
if(x->x_nconnections <= 0)
{
- post("%s_buf_size: no clients connected", objName);
+ if (x->x_verbosity > 0) post("%s_buf_size: no clients connected", objName);
return;
}
/* get number of client (first element in list) */
@@ -770,12 +797,12 @@ static void tcpserver_buf_size(t_tcpserver *x, t_symbol *s, int argc, t_atom *ar
client = atom_getfloatarg(0, argc, argv);
else
{
- post("%s_buf_size: specify client by number", objName);
+ if (x->x_verbosity > 0) post("%s_buf_size: specify client by number", objName);
return;
}
if (!((client > 0) && (client < MAX_CONNECT)))
{
- post("%s__buf_size: client %d out of range [1..%d]", objName, client, MAX_CONNECT);
+ if (x->x_verbosity > 0) post("%s__buf_size: client %d out of range [1..%d]", objName, client, MAX_CONNECT);
return;
}
}
@@ -783,16 +810,16 @@ static void tcpserver_buf_size(t_tcpserver *x, t_symbol *s, int argc, t_atom *ar
{
if (argv[1].a_type != A_FLOAT)
{
- post("%s_buf_size: specify buffer size with a float", objName);
+ if (x->x_verbosity > 0) post("%s_buf_size: specify buffer size with a float", objName);
return;
}
buf_size = atom_getfloatarg(1, argc, argv);
--client;/* zero based index*/
x->x_sr[client]->sr_fdbuf = tcpserver_set_socket_send_buf_size(x->x_sr[client]->sr_fd, (int)buf_size);
- post("%s_buf_size: client %d set to %d", objName, client+1, x->x_sr[client]->sr_fdbuf);
+ if (x->x_verbosity > 0) post("%s_buf_size: client %d set to %d", objName, client+1, x->x_sr[client]->sr_fdbuf);
return;
}
- post("%s_buf_size: specify client and buffer size", objName);
+ if (x->x_verbosity > 0) post("%s_buf_size: specify client and buffer size", objName);
return;
}
@@ -825,25 +852,21 @@ static void *tcpserver_broadcast_thread(void *arg)
f = ttbp->argv[i].a_w.w_float;
d = (int)f;
e = f - d;
-#ifdef DEBUG
- post("%s: argv[%d]: float:%f int:%d delta:%f", objName, i, f, d, e);
-#endif
+ if (ttbp->x->x_verbosity > 1) post("%s: argv[%d]: float:%f int:%d delta:%f", objName, i, f, d, e);
if (e != 0)
{
error("%s_broadcast_thread: item %d (%f) is not an integer", objName, i, f);
- freebytes (arg, sizeof (t_tcpserver_broadcast_params));
+ if (NULL != arg) freebytes (arg, sizeof (t_tcpserver_broadcast_params));
return NULL;
}
if ((d < 0) || (d > 255))
{
error("%s_broadcast_thread: item %d (%f) is not between 0 and 255", objName, i, f);
- freebytes (arg, sizeof (t_tcpserver_broadcast_params));
+ if (NULL != arg) freebytes (arg, sizeof (t_tcpserver_broadcast_params));
return NULL;
}
c = (unsigned char)d; /* make sure it doesn't become negative; this only matters for post() */
-#ifdef DEBUG
- post("%s_broadcast_thread: argv[%d]: %d", objName, i, c);
-#endif
+ if (ttbp->x->x_verbosity > 1) post("%s_broadcast_thread: argv[%d]: %d", objName, i, c);
byte_buf[j++] = c;
if (j >= MAX_UDP_RECEIVE)
{ /* if the argument list is longer than our buffer, send the buffer whenever it's full */
@@ -855,7 +878,7 @@ static void *tcpserver_broadcast_thread(void *arg)
if (tcpserver_send_buffer_avaliable_for_client(ttbp->x, client) < j)
{
error("%s_broadcast_thread: buffer too small for client(%d)", objName, client);
- freebytes (arg, sizeof (t_tcpserver_broadcast_params));
+ if (NULL != arg) freebytes (arg, sizeof (t_tcpserver_broadcast_params));
return NULL;
}
#endif // SIOCOUTQ
@@ -866,8 +889,8 @@ static void *tcpserver_broadcast_thread(void *arg)
if (result <= 0)
{
sys_sockerror("tcpserver_broadcast_thread: send");
- post("%s_broadcast_thread: could not send data to client %d", objName, client+1);
- freebytes (arg, sizeof (t_tcpserver_broadcast_params));
+ if (ttbp->x->x_verbosity > 0) post("%s_broadcast_thread: could not send data to client %d", objName, client+1);
+ if (NULL != arg) freebytes (arg, sizeof (t_tcpserver_broadcast_params));
return NULL;
}
}
@@ -879,26 +902,20 @@ static void *tcpserver_broadcast_thread(void *arg)
else if (ttbp->argv[i].a_type == A_SYMBOL)
{ /* symbols are interpreted to be file names; attempt to load the file and send it */
atom_string(&ttbp->argv[i], fpath, FILENAME_MAX);
-#ifdef DEBUG
- post ("%s_broadcast_thread: fname: %s", objName, fpath);
-#endif
+ if (ttbp->x->x_verbosity > 1) post ("%s_broadcast_thread: fname: %s", objName, fpath);
fptr = sys_fopen(fpath, "rb");
if (fptr == NULL)
{
error("%s_broadcast_thread: unable to open \"%s\"", objName, fpath);
- freebytes (arg, sizeof (t_tcpserver_broadcast_params));
+ if (NULL != arg) freebytes (arg, sizeof (t_tcpserver_broadcast_params));
return NULL;
}
rewind(fptr);
-#ifdef DEBUG
- post("%s_broadcast_thread: d is %d", objName, d);
-#endif
while ((d = fgetc(fptr)) != EOF)
{
+ if (ttbp->x->x_verbosity > 1) post("%s_broadcast_thread: d is %d", objName, d);
byte_buf[j++] = (char)(d & 0x0FF);
-#ifdef DEBUG
- post("%s_broadcast_thread: byte_buf[%d] = %d", objName, j-1, byte_buf[j-1]);
-#endif
+ if (ttbp->x->x_verbosity > 1) post("%s_broadcast_thread: byte_buf[%d] = %d", objName, j-1, byte_buf[j-1]);
if (j >= MAX_UDP_RECEIVE)
{ /* if the file is longer than our buffer, send the buffer whenever it's full */
//LOOP
@@ -910,7 +927,7 @@ static void *tcpserver_broadcast_thread(void *arg)
if (tcpserver_send_buffer_avaliable_for_client(x, client) < j)
{
error("%s_broadcast_thread: buffer too small for client(%d)", objName, client);
- freebytes (arg, sizeof (t_tcpserver_broadcast_params));
+ if (NULL != arg) freebytes (arg, sizeof (t_tcpserver_broadcast_params));
return NULL;
}
#endif // SIOCOUTQ
@@ -921,8 +938,8 @@ static void *tcpserver_broadcast_thread(void *arg)
if (result <= 0)
{
sys_sockerror("tcpserver_broadcast_thread: send");
- post("%s_broadcast_thread: could not send data to client %d", objName, client+1);
- freebytes (arg, sizeof (t_tcpserver_broadcast_params));
+ if (ttbp->x->x_verbosity > 1) post("%s_broadcast_thread: could not send data to client %d", objName, client+1);
+ if (NULL != arg) freebytes (arg, sizeof (t_tcpserver_broadcast_params));
return NULL;
}
}
@@ -934,12 +951,12 @@ static void *tcpserver_broadcast_thread(void *arg)
flen += j;
sys_fclose(fptr);
fptr = NULL;
- post("%s_broadcast_thread: read \"%s\" length %d byte%s", objName, fpath, flen, ((d==1)?"":"s"));
+ if (ttbp->x->x_verbosity > 1) post("%s_broadcast_thread: read \"%s\" length %d byte%s", objName, fpath, flen, ((d==1)?"":"s"));
}
else
{ /* arg was neither a float nor a valid file name */
error("%s_broadcast_thread: item %d is not a float or a file name", objName, i);
- freebytes (arg, sizeof (t_tcpserver_broadcast_params));
+ if (NULL != arg) freebytes (arg, sizeof (t_tcpserver_broadcast_params));
return NULL;
}
}
@@ -953,7 +970,7 @@ static void *tcpserver_broadcast_thread(void *arg)
if (tcpserver_send_buffer_avaliable_for_client(x, client) < length)
{
error("%s_broadcast_thread: buffer too small for client(%d)", objName, client);
- freebytes (arg, sizeof (t_tcpserver_broadcast_params));
+ if (NULL != arg) freebytes (arg, sizeof (t_tcpserver_broadcast_params));
return NULL;
}
#endif // SIOCOUTQ
@@ -964,16 +981,16 @@ static void *tcpserver_broadcast_thread(void *arg)
if (result <= 0)
{
sys_sockerror("tcpserver_broadcast_thread: send");
- post("%s_broadcast_thread: could not send data to client %d", objName, client+1);
- freebytes (arg, sizeof (t_tcpserver_broadcast_params));
+ if (ttbp->x->x_verbosity > 0) post("%s_broadcast_thread: could not send data to client %d", objName, client+1);
+ if (NULL != arg) freebytes (arg, sizeof (t_tcpserver_broadcast_params));
return NULL;
}
}
}
flen += length;
}
- else post("%s_broadcast_thread: not a valid socket number (%d)", objName, sockfd);
- freebytes (arg, sizeof (t_tcpserver_broadcast_params));
+ else if (ttbp->x->x_verbosity > 0) post("%s_broadcast_thread: not a valid socket number (%d)", objName, sockfd);
+ if (NULL != arg) freebytes (arg, sizeof (t_tcpserver_broadcast_params));
return NULL;
}
@@ -984,7 +1001,7 @@ static void tcpserver_broadcast(t_tcpserver *x, t_symbol *s, int argc, t_atom *a
int i;
t_tcpserver_broadcast_params *ttbp;
pthread_t broadcast_thread;
- pthread_attr_t broadcast_attr;
+ pthread_attr_t broadcast_attr = {{0}};
int broadcast_thread_result;
if (x->x_nconnections != 0)
@@ -1005,7 +1022,7 @@ static void tcpserver_broadcast(t_tcpserver *x, t_symbol *s, int argc, t_atom *a
ttbp = (t_tcpserver_broadcast_params *)getbytes(sizeof(t_tcpserver_broadcast_params));
if (ttbp == NULL)
{
- error("%s_broadcast: unable to allocate %lu bytes for t_tcpserver_broadcast_params", objName, sizeof(t_tcpserver_broadcast_params));
+ error("%s_broadcast: unable to allocate %zu bytes for t_tcpserver_broadcast_params", objName, sizeof(t_tcpserver_broadcast_params));
}
else
{
@@ -1015,16 +1032,24 @@ static void tcpserver_broadcast(t_tcpserver *x, t_symbol *s, int argc, t_atom *a
if (0 != (broadcast_thread_result = pthread_create(&broadcast_thread, &broadcast_attr, tcpserver_broadcast_thread, (void *)ttbp)))
{
error("%s_broadcast: couldn't create broadcast thread (%d)", objName, broadcast_thread_result);
- freebytes (ttbp, sizeof (t_tcpserver_broadcast_params));
+ if (NULL != ttbp)
+ {
+ freebytes (ttbp, sizeof (t_tcpserver_broadcast_params));
+ ttbp = NULL;
+ }
}
}
}
+ if (0!= (broadcast_thread_result = pthread_attr_destroy(&broadcast_attr)))
+ {
+ error("%s_broadcast: pthread_attr_destroy failed: %d", objName, broadcast_thread_result);
+ }
}
}
}
/* ---------------- main tcpserver (receive) stuff --------------------- */
-/* tcpserver_notify is called by */
+/* tcpserver_notify is called when socket has closed */
static void tcpserver_notify(t_tcpserver *x)
{
int i, k;
@@ -1044,7 +1069,7 @@ static void tcpserver_notify(t_tcpserver *x)
outlet_float(x->x_sockout, x->x_sr[i]->sr_fd); /* the socket number */
outlet_float(x->x_connectout, x->x_nconnections);
/* /Ivica Ico Bukvic */
- post("%s: \"%s\" removed from list of clients", objName, x->x_sr[i]->sr_host->s_name);
+ if (x->x_verbosity > 0) post("%s: \"%s\" removed from list of clients", objName, x->x_sr[i]->sr_host->s_name);
tcpserver_socketreceiver_free(x->x_sr[i]);
x->x_sr[i] = NULL;
@@ -1069,11 +1094,11 @@ static void tcpserver_connectpoll(t_tcpserver *x)
if (MAX_CONNECT <= x->x_nconnections)
{ /* no more free space for t_tcpserver_socketreceiver pointers, maybe increase MAX_CONNECT? */
- post("%s: too many connections (MAX_CONNECT is %d)", objName, x->x_nconnections);
+ if (x->x_verbosity > 0) post("%s: too many connections (MAX_CONNECT is %d)", objName, x->x_nconnections);
return;
}
fd = accept(x->x_connectsocket, (struct sockaddr*)&incomer_address, &sockaddrl);
- if (fd < 0) post("%s: accept failed", objName);
+ if ((fd < 0)&&(x->x_verbosity > 1)) post("%s: accept failed", objName);
else
{
t_tcpserver_socketreceiver *y = tcpserver_socketreceiver_new((void *)x,
@@ -1093,7 +1118,7 @@ static void tcpserver_connectpoll(t_tcpserver *x)
x->x_sr[i] = y;
x->x_sr[i]->sr_host = gensym(inet_ntoa(incomer_address.sin_addr));
x->x_sr[i]->sr_fd = fd;
- post("%s: accepted connection from %s on socket %d",
+ if (x->x_verbosity > 0) post("%s: accepted connection from %s on socket %d",
objName, x->x_sr[i]->sr_host->s_name, x->x_sr[i]->sr_fd);
/* see how big the send buffer is on this socket */
x->x_sr[i]->sr_fdbuf = 0;
@@ -1103,14 +1128,14 @@ static void tcpserver_connectpoll(t_tcpserver *x)
/* post("%s_connectpoll: send buffer is %ld\n", objName, optVal); */
x->x_sr[i]->sr_fdbuf = optVal;
}
- else post("%s_connectpoll: getsockopt returned %d\n", objName, WSAGetLastError());
+ else if (x->x_verbosity > 1) post("%s_connectpoll: getsockopt returned %d\n", objName, WSAGetLastError());
#else
if (getsockopt(x->x_sr[i]->sr_fd, SOL_SOCKET, SO_SNDBUF, (char*)&optVal, &optLen) == 0)
{
/* post("%s_connectpoll: send buffer is %ld\n", objName, optVal); */
x->x_sr[i]->sr_fdbuf = optVal;
}
- else post("%s_connectpoll: getsockopt returned %d\n", objName, errno);
+ else if (x->x_verbosity > 1) post("%s_connectpoll: getsockopt returned %d\n", objName, errno);
#endif
x->x_sr[i]->sr_addr = ntohl(incomer_address.sin_addr.s_addr);
x->x_addrbytes[0].a_w.w_float = (x->x_sr[i]->sr_addr & 0xFF000000)>>24;
@@ -1159,7 +1184,7 @@ static void tcpserver_port(t_tcpserver*x, t_floatarg fportno)
if(x->x_nconnections > 0)
{
- post ("%s: can't change port (connection count is %d)", objName, x->x_nconnections);
+ if (x->x_verbosity > 0) post ("%s: can't change port (connection count is %d)", objName, x->x_nconnections);
return;
}
@@ -1176,9 +1201,7 @@ static void tcpserver_port(t_tcpserver*x, t_floatarg fportno)
/* create a whole new socket */
sockfd = socket(AF_INET, SOCK_STREAM, 0);
-#ifdef DEBUG
- post("%s: receive socket %d", objName, sockfd);
-#endif
+ if (x->x_verbosity > 1) post("%s: receive socket %d", objName, sockfd);
if (sockfd < 0)
{
sys_sockerror("tcpserver: socket");
@@ -1245,9 +1268,6 @@ static void *tcpserver_new(t_floatarg fportno)
/* create a socket */
sockfd = socket(AF_INET, SOCK_STREAM, 0);
-#ifdef DEBUG
- post("%s: receive socket %d", objName, sockfd);
-#endif
if (sockfd < 0)
{
sys_sockerror("tcpserver: socket");
@@ -1308,7 +1328,8 @@ static void *tcpserver_new(t_floatarg fportno)
x->x_addrbytes[i].a_w.w_float = 0;
}
x->x_port = portno;
- post ("tcpserver listening on port %d", x->x_port);
+ post ("tcpserver listening on port %d, socket %d", x->x_port, sockfd);
+ x->x_verbosity = 0; // stop talking to console unless we're asked
return (x);
}
@@ -1317,25 +1338,29 @@ static void tcpserver_free(t_tcpserver *x)
{
int i;
- post("tcp_server_free...");
+ if (x->x_verbosity > 1) post("tcp_server_free...");
for(i = 0; i < MAX_CONNECT; i++)
{
if (x->x_sr[i] != NULL)
{
+ if (x->x_verbosity > 1) post("tcp_server_free...freeing %d", i);
if (x->x_sr[i]->sr_fd >= 0)
{
- sys_rmpollfn(x->x_sr[i]->sr_fd);
+ if (x->x_verbosity > 1) post("tcp_server_free...freeing fd %d", x->x_sr[i]->sr_fd);
+ sys_rmpollfn(x->x_sr[i]->sr_fd); // sometimes is not found as poll function was already removed
sys_closesocket(x->x_sr[i]->sr_fd);
}
tcpserver_socketreceiver_free(x->x_sr[i]);
+ x->x_sr[i] = NULL;
}
}
if (x->x_connectsocket >= 0)
{
+ if (x->x_verbosity > 1) post("tcp_server_free...freeing connectsocket %d", x->x_connectsocket);
sys_rmpollfn(x->x_connectsocket);
sys_closesocket(x->x_connectsocket);
}
- post("...tcp_server_free");
+ if (x->x_verbosity > 1) post("tcp_server_free end");
}
void tcpserver_setup(void)
@@ -1352,6 +1377,7 @@ void tcpserver_setup(void)
class_addmethod(tcpserver_class, (t_method)tcpserver_unblock, gensym("unblock"), 0);
class_addmethod(tcpserver_class, (t_method)tcpserver_broadcast, gensym("broadcast"), A_GIMME, 0);
class_addmethod(tcpserver_class, (t_method)tcpserver_port, gensym("port"), A_FLOAT, 0);
+ class_addmethod(tcpserver_class, (t_method)tcpserver_verbosity, gensym("verbosity"), A_DEFFLOAT, 0);
class_addlist(tcpserver_class, (t_method)tcpserver_send);
}