aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIOhannes m zmölnig <zmoelnig@users.sourceforge.net>2010-03-30 12:45:22 +0000
committerIOhannes m zmölnig <zmoelnig@users.sourceforge.net>2010-03-30 12:45:22 +0000
commitabce3c4b1b6a04399e85a4a1a92736a426ba8d62 (patch)
treef7e804fd192ddd1329881cf6be2c81574d47c21a
parent69ef9995cf33769b9f2011b50fa94d28c0a8366d (diff)
tcpserver now does not fail to create if port is already in use
with the "port" message, the listening port can be changed at runtime (LATER we also want to query the port...) svn path=/trunk/externals/iem/iemnet/; revision=13316
-rw-r--r--tcpserver.c86
1 files changed, 63 insertions, 23 deletions
diff --git a/tcpserver.c b/tcpserver.c
index 710f472..88feb0e 100644
--- a/tcpserver.c
+++ b/tcpserver.c
@@ -64,7 +64,7 @@ typedef struct _tcpserver
t_int x_nconnections;
t_int x_connectsocket; /* socket waiting for new connections */
-
+ t_int x_port;
int x_defaultclient; /* the default connection to send to; 0=broadcast; >0 use this client; <0 exclude this client */
} t_tcpserver;
@@ -188,6 +188,15 @@ static void tcpserver_info_client(t_tcpserver *x, int client)
}
}
+
+static void tcpserver_info(t_tcpserver *x) {
+ static t_atom output_atom[4];
+
+ SETFLOAT (output_atom+0, x->x_port);
+ outlet_anything( x->x_statout, gensym("port"), 1, output_atom);
+}
+
+
static void tcpserver_info_connection(t_tcpserver *x, t_tcpserver_socketreceiver*y)
{
iemnet__addrout(x->x_statout, x->x_addrout, y->sr_host, y->sr_port);
@@ -457,23 +466,28 @@ static void tcpserver_connectpoll(t_tcpserver *x)
outlet_float(x->x_connectout, x->x_nconnections);
}
-static void *tcpserver_new(t_floatarg fportno)
+static void tcpserver_port(t_tcpserver*x, t_floatarg fportno)
{
- t_tcpserver *x;
- int i;
+ static t_atom ap[1];
+ int portno = fportno;
struct sockaddr_in server;
- int sockfd, portno = fportno;
+ int sockfd = x->x_connectsocket;
+ SETFLOAT(ap, -1);
+ if(x->x_port == portno) {
+ return;
+ }
+
+ /* cleanup any open ports */
+ if(sockfd>=0) {
+ sys_rmpollfn(sockfd);
+ sys_closesocket(sockfd);
+ x->x_connectsocket=-1;
+ x->x_port=-1;
+ }
+
- /* create a socket */
sockfd = socket(AF_INET, SOCK_STREAM, 0);
- DEBUG("receive socket %d", sockfd);
- if (sockfd < 0)
- {
- sys_sockerror("tcpserver: socket");
- // LATER allow creation even if port is in use
- return (0);
- }
server.sin_family = AF_INET;
@@ -487,17 +501,12 @@ static void *tcpserver_new(t_floatarg fportno)
{
sys_sockerror("tcpserver: bind");
sys_closesocket(sockfd);
- return (0);
+ outlet_anything(x->x_statout, gensym("port"), 1, ap);
+ return;
}
- x = (t_tcpserver *)pd_new(tcpserver_class);
-
- x->x_msgout = outlet_new(&x->x_obj, 0); /* 1st outlet for received data */
- x->x_connectout = outlet_new(&x->x_obj, 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 */
-
+ // LATER find out which port is used (useful when assigning "0")
+ portno=ntohs((uint16_t)server.sin_port);
/* streaming protocol */
if (listen(sockfd, 5) < 0)
@@ -505,6 +514,8 @@ static void *tcpserver_new(t_floatarg fportno)
sys_sockerror("tcpserver: listen");
sys_closesocket(sockfd);
sockfd = -1;
+ outlet_anything(x->x_statout, gensym("port"), 1, ap);
+ return;
}
else
{
@@ -512,6 +523,30 @@ static void *tcpserver_new(t_floatarg fportno)
}
x->x_connectsocket = sockfd;
+ x->x_port = portno;
+
+
+ SETFLOAT(ap, x->x_port);
+ outlet_anything(x->x_statout, gensym("port"), 1, ap);
+
+}
+
+static void *tcpserver_new(t_floatarg fportno)
+{
+ t_tcpserver *x;
+ int i;
+
+ x = (t_tcpserver *)pd_new(tcpserver_class);
+
+ x->x_msgout = outlet_new(&x->x_obj, 0); /* 1st outlet for received data */
+ x->x_connectout = outlet_new(&x->x_obj, 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 */
+
+
+ x->x_connectsocket = -1;
+ x->x_port = -1;
x->x_nconnections = 0;
for(i = 0; i < MAX_CONNECT; i++)
@@ -521,6 +556,8 @@ static void *tcpserver_new(t_floatarg fportno)
x->x_defaultclient=0;
+ tcpserver_port(x, fportno);
+
return (x);
}
@@ -559,8 +596,11 @@ IEMNET_EXTERN void tcpserver_setup(void)
class_addmethod(tcpserver_class, (t_method)tcpserver_broadcast, gensym("broadcast"), A_GIMME, 0);
class_addmethod(tcpserver_class, (t_method)tcpserver_defaulttarget, gensym("target"), A_DEFFLOAT, 0);
- class_addlist(tcpserver_class, (t_method)tcpserver_defaultsend);
+ class_addlist (tcpserver_class, (t_method)tcpserver_defaultsend);
+
+ class_addmethod(tcpserver_class, (t_method)tcpserver_port, gensym("port"), A_DEFFLOAT, 0);
+ class_addbang (tcpserver_class, (t_method)tcpserver_info);
post("iemnet: networking with Pd :: %s", objName);
post(" (c) 2010 IOhannes m zmoelnig, IEM");