From e6edce911941c2006a6a7c9f1f2819eb274ff81c Mon Sep 17 00:00:00 2001 From: Martin Peach Date: Wed, 8 Apr 2009 18:35:29 +0000 Subject: Added [timeout( message to set microsecond timeout for send. This gives time for unusually small buffers to clear. Set default timeout to 1000us. Also prints a message if the whole send didn't complete. Updated help patch to match. svn path=/trunk/externals/mrpeach/; revision=10986 --- net/tcpserver-help.pd | 53 +++++++++++++++++++++++++++------------------------ net/tcpserver.c | 39 ++++++++++++++++++++++++++++--------- 2 files changed, 58 insertions(+), 34 deletions(-) (limited to 'net') diff --git a/net/tcpserver-help.pd b/net/tcpserver-help.pd index e56209d..5e7b041 100644 --- a/net/tcpserver-help.pd +++ b/net/tcpserver-help.pd @@ -1,4 +1,4 @@ -#N canvas 220 28 1204 762 12; +#N canvas 284 35 1256 779 12; #X msg 143 -36 print; #X floatatom 448 290 5 0 0 0 - - -; #X floatatom 472 340 5 0 0 0 - - -; @@ -17,31 +17,31 @@ #X text 402 340 on socket; #X msg 93 -86 send 504 1 2 3; #X text 204 -91 send to client on socket 504; -#X msg 714 -228 client 1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 +#X msg 777 -209 client 1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19; -#X msg 714 -205 client 1 20 21 22 23 24 25 26 27 28 29 30 31 32 33 +#X msg 777 -186 client 1 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39; -#X msg 714 -167 client 1 40 41 42 43 44 45 46 47 48 49 50 51 52 53 +#X msg 777 -148 client 1 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59; -#X msg 714 -129 client 1 60 61 62 63 64 65 66 67 68 69 70 71 72 73 +#X msg 777 -110 client 1 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79; -#X msg 714 -91 client 1 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 +#X msg 777 -72 client 1 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99; -#X msg 714 -53 client 1 100 101 102 103 104 105 106 107 108 109 110 +#X msg 777 -34 client 1 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119; -#X msg 714 -15 client 1 120 121 122 123 124 125 126 127 138 139 140 -141 142 143 144 145 146 147 148 149; -#X msg 714 23 client 1 150 151 152 153 154 155 156 157 158 159 160 +#X msg 777 4 client 1 120 121 122 123 124 125 126 127 138 139 140 141 +142 143 144 145 146 147 148 149; +#X msg 777 42 client 1 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169; -#X msg 714 61 client 1 170 171 172 173 174 175 176 177 178 179 180 +#X msg 777 80 client 1 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189; -#X msg 714 99 client 1 190 191 192 193 194 195 196 197 198 199 200 +#X msg 777 118 client 1 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209; -#X msg 714 137 client 1 210 211 212 213 214 215 216 217 218 219 220 +#X msg 777 156 client 1 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229; -#X msg 714 175 client 1 230 231 232 233 234 235 236 237 238 239 240 +#X msg 777 194 client 1 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249; -#X msg 714 213 client 1 250 251 252 253 254 255; +#X msg 777 232 client 1 250 251 252 253 254 255; #X obj 144 -203 openpanel; #X obj 144 -222 bng 15 250 50 0 empty empty choose_a_file 17 7 0 10 -24198 -241291 -1; @@ -52,7 +52,7 @@ #X text 192 -57 (the first number is socket number); #X msg 63 -116 disconnectsocket \$1; #X msg 20 -159 disconnectclient \$1; -#X obj 714 238 s toserver; +#X obj 777 257 s toserver; #X obj 425 238 r toserver; #X floatatom 247 -198 5 0 0 0 - - -; #X obj 225 -179 f; @@ -69,17 +69,17 @@ hang pd!; #X obj 425 393 spigot; #X obj 464 373 tgl 15 0 empty empty enable_print 17 7 0 10 -24198 -258699 --45076 1 1; +-45076 0 1; #X msg 263 84 dump \$1; #X obj 87 69 tgl 15 0 empty empty enable_dump 17 7 0 10 -4034 -257985 --1 1 1; +-1 0 1; #X text 19 19 dump received; #X text 19 35 characters to main; #X text 19 50 window in hexdump; #X text 19 66 format:; #X obj 425 266 tcpserver 9997; #X msg -28 -207 client 1 test.txt; -#X text 714 -253 [tcpserver] sends and receives bytes on [0...255] +#X text 777 -234 [tcpserver] sends and receives bytes on [0...255] ; #X text 262 -243 [tcpserver] waits for clients to connect to its port. ; @@ -111,11 +111,13 @@ hang pd!; #X obj 642 325 unpack 0 0 0; #X floatatom 723 392 5 0 0 0 - - -; #X text 653 391 on_socket; -#X text 35 450 2009/03/09 Martin Peach; -#X msg 344 165 send; -#X msg 369 190 1156; -#X text 387 164 output 'client' message for all sockets; -#X text 409 190 output 'client' message for socket 1156; +#X msg 363 184 send; +#X msg 388 209 1156; +#X text 406 183 output 'client' message for all sockets; +#X text 428 209 output 'client' message for socket 1156; +#X msg 338 159 timeout 100; +#X text 425 159 microsecond timeout for send (default is 1000); +#X text 35 450 2009/04/08 Martin Peach; #X connect 0 0 60 0; #X connect 3 0 4 0; #X connect 3 1 5 0; @@ -174,5 +176,6 @@ hang pd!; #X connect 89 0 68 0; #X connect 89 1 66 0; #X connect 89 2 90 0; +#X connect 92 0 60 0; #X connect 93 0 60 0; -#X connect 94 0 60 0; +#X connect 96 0 60 0; diff --git a/net/tcpserver.c b/net/tcpserver.c index 9090c66..7dcaa8c 100644 --- a/net/tcpserver.c +++ b/net/tcpserver.c @@ -82,7 +82,7 @@ typedef struct _tcpserver t_outlet *x_connectout; t_outlet *x_sockout; t_outlet *x_addrout; - t_outlet *x_status_outlet; + t_outlet *x_status_outlet; t_int x_dump; // 1 = hexdump received bytes t_symbol *x_host[MAX_CONNECT]; t_int x_fd[MAX_CONNECT]; @@ -93,6 +93,7 @@ typedef struct _tcpserver t_int x_sock_fd; t_int x_connectsocket; t_int x_nconnections; + t_int x_timeout_us; t_atom x_msgoutbuf[MAX_UDP_RECEIVE]; char x_msginbuf[MAX_UDP_RECEIVE]; } t_tcpserver; @@ -104,7 +105,7 @@ static void tcpserver_socketreceiver_read(t_tcpserver_socketreceiver *x, int fd) static void tcpserver_socketreceiver_free(t_tcpserver_socketreceiver *x); static void tcpserver_send(t_tcpserver *x, t_symbol *s, int argc, t_atom *argv); static void tcpserver_send_bytes(int sockfd, t_tcpserver *x, int argc, t_atom *argv); -static size_t tcpserver_send_buf(int client, int sockfd, char *byte_buf, size_t length); +static size_t tcpserver_send_buf(int client, int sockfd, char *byte_buf, size_t length, t_int timeout_us); static void tcpserver_client_send(t_tcpserver *x, t_symbol *s, int argc, t_atom *argv); static void tcpserver_output_client_state(t_tcpserver *x, int client); static int tcpserver_get_socket_send_buf_size(int sockfd); @@ -121,8 +122,23 @@ static void *tcpserver_new(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_timeout(t_tcpserver *x, t_float timeout); static void tcpserver_hexdump(unsigned char *buf, long len); +static void tcpserver_timeout(t_tcpserver *x, t_float timeout) +{ + /* set the timeout on the select call in tcpserver_send_buf */ + /* this is the maximum time in microseconds to wait */ + /* before abandoning attempt to send */ + + t_int timeout_us = 0; + if ((timeout >= 0)&&(timeout < 1000000)) + { + timeout_us = (t_int)timeout; + x->x_timeout_us = timeout_us; + } +} + static void tcpserver_dump(t_tcpserver *x, t_float dump) { x->x_dump = (dump == 0)?0:1; @@ -353,7 +369,7 @@ static void tcpserver_send_bytes(int client, t_tcpserver *x, int argc, t_atom *a #endif if (j >= MAX_UDP_RECEIVE) { - flen += tcpserver_send_buf(client, sockfd, byte_buf, j); + flen += tcpserver_send_buf(client, sockfd, byte_buf, j, x->x_timeout_us); j = 0; } } @@ -371,7 +387,7 @@ static void tcpserver_send_bytes(int client, t_tcpserver *x, int argc, t_atom *a length = j; if (length > 0) { - flen += tcpserver_send_buf(client, sockfd, byte_buf, length); + flen += tcpserver_send_buf(client, sockfd, byte_buf, length, x->x_timeout_us); } } else post("%s: not a valid socket number (%d)", objName, sockfd); @@ -381,7 +397,7 @@ static void tcpserver_send_bytes(int client, t_tcpserver *x, int argc, t_atom *a outlet_anything( x->x_status_outlet, gensym("sent"), 3, output_atom); } -static size_t tcpserver_send_buf(int client, int sockfd, char *byte_buf, size_t length) +static size_t tcpserver_send_buf(int client, int sockfd, char *byte_buf, size_t length, t_int timeout_us) { char *bp; size_t sent = 0; @@ -394,8 +410,8 @@ static size_t tcpserver_send_buf(int client, int sockfd, char *byte_buf, size_t { FD_ZERO(&wfds); FD_SET(sockfd, &wfds); - timeout.tv_sec = 0; /* give it no time to clear buffer */ - timeout.tv_usec = 0; + timeout.tv_sec = 0; + timeout.tv_usec = timeout_us; /* give it a short time to clear buffer */ result = select(sockfd+1, NULL, &wfds, NULL, &timeout); if (result == -1) { @@ -417,7 +433,11 @@ static size_t tcpserver_send_buf(int client, int sockfd, char *byte_buf, size_t bp += result; } } - else return sent;/* abandon any further attempts to send so we don't block */ + else + { + post ("%s_send_buf: can't send right now, sent %lu of %lu", objName, sent, length); + return sent;/* abandon any further attempts to send so we don't block */ + } } return sent; } @@ -865,7 +885,7 @@ static void *tcpserver_new(t_floatarg fportno) x->x_addrbytes[i].a_type = A_FLOAT; x->x_addrbytes[i].a_w.w_float = 0; } - + x->x_timeout_us = 1000;/* default 1 ms for select call timeout when sending */ return (x); } @@ -902,6 +922,7 @@ void tcpserver_setup(void) class_addmethod(tcpserver_class, (t_method)tcpserver_socket_disconnect, gensym("disconnectsocket"), A_DEFFLOAT, 0); class_addmethod(tcpserver_class, (t_method)tcpserver_dump, gensym("dump"), A_FLOAT, 0); class_addmethod(tcpserver_class, (t_method)tcpserver_broadcast, gensym("broadcast"), A_GIMME, 0); + class_addmethod(tcpserver_class, (t_method)tcpserver_timeout, gensym("timeout"), A_FLOAT, 0); class_addlist(tcpserver_class, (t_method)tcpserver_send); } -- cgit v1.2.1