aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Peach <mrpeach@users.sourceforge.net>2013-05-20 22:37:36 +0000
committerMartin Peach <mrpeach@users.sourceforge.net>2013-05-20 22:37:36 +0000
commit6e8398df98237d7cf85fc14e369534f7ffa833a9 (patch)
tree7a5e66d9468b3f4af881a2afbe37dabdfb51c71d
parent79e1b8050cd2bc4199d90dbf86c9bdc5fc87cf09 (diff)
Added a port method to change the listening port.
svn path=/trunk/externals/mrpeach/; revision=17143
-rw-r--r--net/tcpserver-help.pd86
-rw-r--r--net/tcpserver.c97
2 files changed, 141 insertions, 42 deletions
diff --git a/net/tcpserver-help.pd b/net/tcpserver-help.pd
index 097b785..13defdc 100644
--- a/net/tcpserver-help.pd
+++ b/net/tcpserver-help.pd
@@ -1,20 +1,20 @@
-#N canvas 1 53 1284 779 12;
+#N canvas 322 104 1272 779 12;
#X msg 39 -10 print;
-#X floatatom 344 316 5 0 0 0 - - -;
-#X floatatom 368 366 5 0 0 0 - - -;
-#X obj 392 317 unpack 0 0 0 0;
-#X floatatom 392 340 3 0 0 0 - - -;
-#X floatatom 423 340 3 0 0 0 - - -;
-#X floatatom 455 340 3 0 0 0 - - -;
-#X floatatom 489 340 3 0 0 0 - - -;
-#X text 349 339 from;
-#X text 260 316 connections;
-#X obj 321 441 print received;
+#X floatatom 404 376 5 0 0 0 - - -;
+#X floatatom 428 426 5 0 0 0 - - -;
+#X obj 452 377 unpack 0 0 0 0;
+#X floatatom 452 400 3 0 0 0 - - -;
+#X floatatom 483 400 3 0 0 0 - - -;
+#X floatatom 515 400 3 0 0 0 - - -;
+#X floatatom 549 400 3 0 0 0 - - -;
+#X text 409 399 from;
+#X text 320 376 connections;
+#X obj 381 501 print received;
#X msg 135 86 client 1 1 2 3;
#X msg 63 14 broadcast 1 2 3;
#X text 91 -9 list of connections;
#X text 186 14 send to all clients;
-#X text 298 366 on socket;
+#X text 358 426 on socket;
#X msg -11 -60 send 504 1 2 3;
#X text 100 -65 send to client on socket 504;
#X msg 647 -209 client 1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
@@ -53,7 +53,7 @@
#X msg -41 -90 disconnectsocket \$1;
#X msg -84 -133 disconnectclient \$1;
#X obj 647 257 s toserver;
-#X obj 321 264 r toserver;
+#X obj 381 324 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
@@ -63,12 +63,12 @@
#X obj 163 -129 bng 15 250 50 0 empty empty empty 17 7 0 10 -258699
-241291 -1;
#X text -109 -110 disconnect by socket or client number;
-#X text 428 291 argument is port number;
-#X text -8 293 Received messages are output as lists of bytes;
-#X text -69 397 ***WARNING*** Attempting to print long messages can
+#X text 488 351 argument is port number;
+#X text 52 353 Received messages are output as lists of bytes;
+#X text -9 457 ***WARNING*** Attempting to print long messages can
hang pd!;
-#X obj 321 419 spigot;
-#X obj 360 399 tgl 15 0 empty empty enable_print 17 7 0 10 -24198 -258699
+#X obj 381 479 spigot;
+#X obj 420 459 tgl 15 0 empty empty enable_print 17 7 0 10 -24198 -258699
-45076 0 1;
#X msg 159 110 dump \$1;
#X obj -17 95 tgl 15 0 empty empty enable_dump 17 7 0 10 -4034 -257985
@@ -77,7 +77,7 @@ hang pd!;
#X text -85 61 characters to main;
#X text -85 76 window in hexdump;
#X text -85 92 format:;
-#X obj 321 292 tcpserver 9997;
+#X obj 381 352 tcpserver 9997;
#X msg -132 -181 client 1 test.txt;
#X text 647 -234 [tcpserver] sends and receives bytes on [0...255]
;
@@ -85,41 +85,40 @@ hang pd!;
;
#X text -137 -202 send a file to client 1;
#X msg 183 134 client 1 72 101 108 108 111 13 10;
-#X floatatom 578 377 9 0 0 0 - - -;
-#X obj 710 336 print status;
-#X floatatom 538 400 5 0 0 0 - - -;
-#X text 468 399 to_client;
+#X floatatom 638 437 9 0 0 0 - - -;
+#X obj 770 396 print status;
+#X floatatom 598 460 5 0 0 0 - - -;
+#X text 528 459 to_client;
#X msg 111 62 client;
#X msg 88 39 client 1;
#X text 156 38 get state of client 1;
#X text 249 86 send (binary) 1 2 3 to client 1;
-#X floatatom 712 469 5 0 0 0 - - -;
-#X symbolatom 744 442 20 0 0 0 - - -;
-#X floatatom 681 442 5 0 0 0 - - -;
-#X text 645 376 bytes;
-#X text 538 376 sent;
+#X floatatom 772 529 5 0 0 0 - - -;
+#X symbolatom 804 502 20 0 0 0 - - -;
+#X floatatom 741 502 5 0 0 0 - - -;
+#X text 705 436 bytes;
+#X text 598 436 sent;
#X msg 209 160 clientbuf 1 65536;
-#X obj 681 418 unpack 0 0 s 0;
-#X floatatom 776 490 7 0 0 0 - - -;
-#X text 621 490 length of send buffer:;
-#X text 661 468 socket:;
-#X text 630 441 client:;
-#X text 721 441 ip:;
+#X obj 741 478 unpack 0 0 s 0;
+#X floatatom 836 550 7 0 0 0 - - -;
+#X text 681 550 length of send buffer:;
+#X text 721 528 socket:;
+#X text 690 501 client:;
+#X text 781 501 ip:;
#X text 339 159 set send-buffer size for client 1;
#X text 163 62 get state of all clients (list on right outlet);
-#X obj 538 351 unpack 0 0 0;
-#X floatatom 619 418 5 0 0 0 - - -;
-#X text 549 417 on_socket;
+#X obj 598 411 unpack 0 0 0;
+#X floatatom 679 478 5 0 0 0 - - -;
+#X text 609 477 on_socket;
#X msg 233 184 send;
#X msg 258 209 1156;
#X text 276 183 output 'client' message for all sockets;
#X text 298 209 output 'client' message for socket 1156;
#X msg 283 234 unblock;
-#X obj 538 312 route sent client blocked;
+#X obj 598 372 route sent client blocked;
#X text -143 233 If sending too many messages blocks the system \,
tcpserver will stop sending until it receives an unblock message;
-#X obj 652 359 print blocked;
-#X text -69 476 2010/03/27 Martin Peach;
+#X obj 712 419 print blocked;
#N canvas 529 82 494 344 META 0;
#X text 12 225 HELP_PATCH_AUTHORS "pd meta" information added by Jonathan
Wilkes for Pd version 0.42.;
@@ -134,7 +133,11 @@ send print broadcast dump clientbuf unblock;
#X text 12 145 OUTLET_2 float;
#X text 12 165 OUTLET_3 list;
#X text 12 185 OUTLET_4 sent client blocked;
-#X restore 839 398 pd META;
+#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 text -9 536 2013/05/20 Martin Peach;
#X connect 0 0 60 0;
#X connect 3 0 4 0;
#X connect 3 1 5 0;
@@ -197,3 +200,4 @@ send print broadcast dump clientbuf unblock;
#X connect 96 1 80 0;
#X connect 96 2 98 0;
#X connect 96 3 67 0;
+#X connect 100 0 60 0;
diff --git a/net/tcpserver.c b/net/tcpserver.c
index 379a7ec..ca872b4 100644
--- a/net/tcpserver.c
+++ b/net/tcpserver.c
@@ -112,6 +112,7 @@ typedef struct _tcpserver
t_atom x_addrbytes[4];
t_int x_sock_fd;
t_int x_connectsocket;
+ t_int x_port;
t_int x_nconnections;
t_int x_blocked;
t_atom x_msgoutbuf[MAX_UDP_RECEIVE];
@@ -151,6 +152,7 @@ static void tcpserver_connectpoll(t_tcpserver *x);
static void tcpserver_print(t_tcpserver *x);
static void tcpserver_unblock(t_tcpserver *x);
static void *tcpserver_new(t_floatarg fportno);
+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);
@@ -1142,6 +1144,96 @@ static void tcpserver_unblock(t_tcpserver *x)
x->x_blocked = 0;
}
+static void tcpserver_port(t_tcpserver*x, t_floatarg fportno)
+{
+ t_atom output_atom;
+ int portno = fportno;
+ struct sockaddr_in server;
+ socklen_t serversize = sizeof(server);
+ int sockfd = x->x_connectsocket;
+ int optVal = 1;
+ int optLen = sizeof(int);
+
+
+ if(x->x_port == portno) return;
+
+ if(x->x_nconnections > 0)
+ {
+ post ("%s: can't change port (connection count is %d)", objName, x->x_nconnections);
+ return;
+ }
+
+ SETFLOAT(&output_atom, -1);
+
+ /* shut down the old socket */
+ if (sockfd >= 0)
+ {
+ sys_rmpollfn(sockfd);
+ sys_closesocket(sockfd);
+ x->x_connectsocket = -1;
+ x->x_port = -1;
+ }
+
+ /* create a whole new 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");
+ return;
+ }
+ server.sin_family = AF_INET;
+ server.sin_addr.s_addr = INADDR_ANY;
+ /* enable reuse of local address */
+#ifdef _WIN32
+ if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char*)&optVal, optLen) == SOCKET_ERROR)
+#else
+ if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char*)&optVal, optLen) == -1)
+#endif
+ sys_sockerror("tcpserver: setsockopt SO_REUSEADDR");
+
+ /* assign server port number */
+ server.sin_port = htons((u_short)portno);
+ /* name the socket */
+ if (bind(sockfd, (struct sockaddr *)&server, serversize) < 0)
+ {
+ sys_sockerror("tcpserver: bind");
+ sys_closesocket(sockfd);
+ outlet_anything(x->x_status_outlet, gensym("port"), 1, &output_atom);
+ return;
+ }
+
+ /* streaming protocol */
+ if (listen(sockfd, 5) < 0)
+ {
+ sys_sockerror("tcpserver: listen");
+ sys_closesocket(sockfd);
+ sockfd = -1;
+ outlet_anything(x->x_status_outlet, gensym("port"), 1, &output_atom);
+ return;
+ }
+ else
+ {
+ sys_addpollfn(sockfd, (t_fdpollfn)tcpserver_connectpoll, x); // wait for new connections
+ }
+
+ x->x_connectsocket = sockfd;
+ x->x_nconnections = 0;
+ x->x_blocked = 0;
+
+
+ // 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(&output_atom, x->x_port);
+ outlet_anything(x->x_status_outlet, gensym("port"), 1, &output_atom);
+}
+
static void *tcpserver_new(t_floatarg fportno)
{
t_tcpserver *x;
@@ -1215,10 +1307,12 @@ static void *tcpserver_new(t_floatarg fportno)
x->x_addrbytes[i].a_type = A_FLOAT;
x->x_addrbytes[i].a_w.w_float = 0;
}
- post ("tcpserver listening on port %d", portno);
+ x->x_port = portno;
+ post ("tcpserver listening on port %d", x->x_port);
return (x);
}
+
static void tcpserver_free(t_tcpserver *x)
{
int i;
@@ -1257,6 +1351,7 @@ void tcpserver_setup(void)
class_addmethod(tcpserver_class, (t_method)tcpserver_dump, gensym("dump"), A_FLOAT, 0);
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_addlist(tcpserver_class, (t_method)tcpserver_send);
}