aboutsummaryrefslogtreecommitdiff
path: root/tcpserver.c
diff options
context:
space:
mode:
authorIOhannes m zmölnig <zmoelnig@users.sourceforge.net>2015-08-31 22:11:51 +0000
committerIOhannes m zmölnig <zmoelnig@users.sourceforge.net>2015-08-31 22:11:51 +0000
commitc5e0079ae1323ad4c35d28f83ce732bb3820c46a (patch)
tree9768e681d9f4905cd04f4a3e4b84a6865a2454b3 /tcpserver.c
parent623fb91ea95294c80ad9748e8959cb7d86568143 (diff)
un-threaded receive
svn path=/trunk/externals/iem/iemnet/; revision=17543
Diffstat (limited to 'tcpserver.c')
-rw-r--r--tcpserver.c553
1 files changed, 327 insertions, 226 deletions
diff --git a/tcpserver.c b/tcpserver.c
index 59b6132..ca4f38e 100644
--- a/tcpserver.c
+++ b/tcpserver.c
@@ -1,5 +1,5 @@
/* tcpserver.c
- * copyright (c) 2010 IOhannes m zmölnig, IEM
+ * copyright (c) 2010 IOhannes m zmölnig, IEM
* copyright (c) 2006-2010 Martin Peach
* copyright (c) 2004 Olaf Matthes
*/
@@ -19,9 +19,8 @@
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
-/* along with this program; if not, write to the Free Software */
-/* Foundation, Inc., */
-/* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
+/* along with this program; if not, see */
+/* http://www.gnu.org/licenses/ */
/* */
/* ---------------------------------------------------------------------------- */
@@ -30,6 +29,8 @@
#include "iemnet.h"
#include "iemnet_data.h"
#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
#define MAX_CONNECT 32 /* maximum number of connections */
@@ -38,45 +39,48 @@
static t_class *tcpserver_class;
static const char objName[] = "tcpserver";
-typedef struct _tcpserver_socketreceiver
-{
+typedef struct _tcpserver_socketreceiver {
struct _tcpserver *sr_owner;
long sr_host;
unsigned short sr_port;
- t_int sr_fd;
+ int sr_fd;
t_iemnet_sender*sr_sender;
t_iemnet_receiver*sr_receiver;
} t_tcpserver_socketreceiver;
-typedef struct _tcpserver
-{
+typedef struct _tcpserver {
t_object x_obj;
t_outlet *x_msgout;
t_outlet *x_connectout;
t_outlet *x_sockout; // legacy
t_outlet *x_addrout; // legacy
- t_outlet *x_statout;
+ t_outlet *x_statout;
int x_serialize;
t_tcpserver_socketreceiver *x_sr[MAX_CONNECT]; /* socket per connection */
- t_int x_nconnections;
+ unsigned int x_nconnections;
- t_int x_connectsocket; /* socket waiting for new connections */
- t_int x_port;
+ int
+ x_connectsocket; /* socket waiting for new connections */
+ int x_port;
- int x_defaulttarget; /* the default connection to send to; 0=broadcast; >0 use this client; <0 exclude this client */
- t_iemnet_floatlist *x_floatlist;
+ int
+ x_defaulttarget; /* the default connection to send to; 0=broadcast; >0 use this client; <0 exclude this client */
+ t_iemnet_floatlist *x_floatlist;
} t_tcpserver;
static void tcpserver_receive_callback(void*x, t_iemnet_chunk*);
-static t_tcpserver_socketreceiver *tcpserver_socketreceiver_new(t_tcpserver *owner, int sockfd, struct sockaddr_in*addr)
+static t_tcpserver_socketreceiver *tcpserver_socketreceiver_new(
+ t_tcpserver *owner, int sockfd, struct sockaddr_in*addr)
{
- t_tcpserver_socketreceiver *x = (t_tcpserver_socketreceiver *)getbytes(sizeof(*x));
+ 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));
+ error("%s_socketreceiver: unable to allocate %d bytes", objName,
+ (int)sizeof(*x));
return NULL;
} else {
x->sr_owner=owner;
@@ -86,8 +90,9 @@ static t_tcpserver_socketreceiver *tcpserver_socketreceiver_new(t_tcpserver *own
x->sr_host=ntohl(addr->sin_addr.s_addr);
x->sr_port=ntohs(addr->sin_port);
- x->sr_sender=iemnet__sender_create(sockfd);
- x->sr_receiver=iemnet__receiver_create(sockfd, x, tcpserver_receive_callback);
+ x->sr_sender=iemnet__sender_create(sockfd, NULL, NULL, 0);
+ x->sr_receiver=iemnet__receiver_create(sockfd, x,
+ tcpserver_receive_callback, 0);
}
return (x);
}
@@ -95,40 +100,41 @@ static t_tcpserver_socketreceiver *tcpserver_socketreceiver_new(t_tcpserver *own
static void tcpserver_socketreceiver_free(t_tcpserver_socketreceiver *x)
{
DEBUG("freeing %x", x);
- if (x != NULL)
- {
- int sockfd=x->sr_fd;
- t_iemnet_sender*sender=x->sr_sender;
- t_iemnet_receiver*receiver=x->sr_receiver;
-
- x->sr_owner=NULL;
- x->sr_sender=NULL;
- x->sr_receiver=NULL;
-
- x->sr_fd=-1;
-
-
- if(sender) iemnet__sender_destroy(sender);
- if(receiver)iemnet__receiver_destroy(receiver);
-
- sys_closesocket(sockfd);
-
-
- freebytes(x, sizeof(*x));
+ if (x != NULL) {
+ int sockfd=x->sr_fd;
+ t_iemnet_sender*sender=x->sr_sender;
+ t_iemnet_receiver*receiver=x->sr_receiver;
+
+ x->sr_owner=NULL;
+ x->sr_sender=NULL;
+ x->sr_receiver=NULL;
+
+ x->sr_fd=-1;
+
+
+ if(sender) {
+ iemnet__sender_destroy(sender, 0);
+ }
+ if(receiver) {
+ iemnet__receiver_destroy(receiver, 0);
}
+
+ iemnet__closesocket(sockfd);
+
+
+ freebytes(x, sizeof(*x));
+ }
DEBUG("freeed %x", x);
}
static int tcpserver_socket2index(t_tcpserver*x, int sockfd)
{
- int i=0;
- for(i = 0; i < x->x_nconnections; i++) /* check if connection exists */
- {
- if(x->x_sr[i]->sr_fd == sockfd)
- {
- return i;
- }
- }
+ unsigned int i=0;
+ for(i = 0; i < x->x_nconnections; i++) { /* check if connection exists */
+ if(x->x_sr[i]->sr_fd == sockfd) {
+ return i;
+ }
+ }
return -1;
}
@@ -138,28 +144,27 @@ 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);
- 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));
- return -1;
- }
+ if(x->x_nconnections <= 0) {
+ pd_error(x, "[%s]: no clients connected", objName);
+ 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));
+ return -1;
+ }
return (client-1);
}
/* ---------------- tcpserver info ---------------------------- */
-static void tcpserver_info_client(t_tcpserver *x, int client)
+static void tcpserver_info_client(t_tcpserver *x, unsigned int client)
{
// "client <id> <socket> <IP> <port>"
// "bufsize <id> <insize> <outsize>"
static t_atom output_atom[4];
- if(x&&x->x_sr&&x->x_sr[client]) {
+ if(x&&client<MAX_CONNECT&&x->x_sr[client]) {
int sockfd = x->x_sr[client]->sr_fd;
unsigned short port = x->x_sr[client]->sr_port;
long address = x->x_sr[client]->sr_host;
@@ -168,7 +173,7 @@ static void tcpserver_info_client(t_tcpserver *x, int client)
int insize =iemnet__receiver_getsize(x->x_sr[client]->sr_receiver);
int outsize=iemnet__sender_getsize (x->x_sr[client]->sr_sender );
- snprintf(hostname, MAXPDSTRING-1, "%d.%d.%d.%d",
+ snprintf(hostname, MAXPDSTRING-1, "%d.%d.%d.%d",
(unsigned char)((address & 0xFF000000)>>24),
(unsigned char)((address & 0x0FF0000)>>16),
(unsigned char)((address & 0x0FF00)>>8),
@@ -190,7 +195,8 @@ static void tcpserver_info_client(t_tcpserver *x, int client)
}
-static void tcpserver_info(t_tcpserver *x) {
+static void tcpserver_info(t_tcpserver *x)
+{
static t_atom output_atom[4];
int sockfd=x->x_connectsocket;
@@ -218,25 +224,26 @@ static void tcpserver_info(t_tcpserver *x) {
}
-static void tcpserver_info_connection(t_tcpserver *x, t_tcpserver_socketreceiver*y)
+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);
outlet_float(x->x_sockout, y->sr_fd);
}
/* ---------------- main tcpserver (send) stuff --------------------- */
-static void tcpserver_disconnect_socket(t_tcpserver *x, t_floatarg fsocket);
-static void tcpserver_send_bytes(t_tcpserver*x, int client, t_iemnet_chunk*chunk)
+static void tcpserver_disconnect_socket(t_tcpserver *x,
+ t_floatarg fsocket);
+
+static void tcpserver_send_bytes_client(t_tcpserver*x,
+ t_tcpserver_socketreceiver*sr, int client, t_iemnet_chunk*chunk)
{
- DEBUG("send_bytes to %x -> %x[%d]", x, x->x_sr, client);
- if(x->x_sr)DEBUG("client %X", x->x_sr[client]);
- if(x && x->x_sr && x->x_sr[client]) {
+ if(sr) {
t_atom output_atom[3];
int size=-1;
- t_iemnet_sender*sender=sender=x->x_sr[client]->sr_sender;
- int sockfd = x->x_sr[client]->sr_fd;
-
+ t_iemnet_sender*sender=sr->sr_sender;
+ int sockfd = sr->sr_fd;
if(sender) {
size=iemnet__sender_send(sender, chunk);
}
@@ -244,7 +251,7 @@ static void tcpserver_send_bytes(t_tcpserver*x, int client, t_iemnet_chunk*chunk
SETFLOAT(&output_atom[0], client+1);
SETFLOAT(&output_atom[1], size);
SETFLOAT(&output_atom[2], sockfd);
- outlet_anything( x->x_statout, gensym("sent"), 3, output_atom);
+ outlet_anything( x->x_statout, gensym("sendbuffersize"), 3, output_atom);
if(size<0) {
// disconnected!
@@ -253,74 +260,119 @@ static void tcpserver_send_bytes(t_tcpserver*x, int client, t_iemnet_chunk*chunk
}
}
+static void tcpserver_send_bytes(t_tcpserver*x, int client,
+ t_iemnet_chunk*chunk)
+{
+ t_tcpserver_socketreceiver*sr=NULL;
+ if(x&&client<MAX_CONNECT) {
+ sr=x->x_sr[client];
+ }
+ DEBUG("send_bytes to %p[%d] -> %p", x, client, sr);
+ tcpserver_send_bytes_client(x, sr, client, chunk);
+}
+/* send the chunk to all non-null clients */
+static void tcpserver_send_bytes_clients(t_tcpserver*x,
+ t_tcpserver_socketreceiver**sr, unsigned int nsr, t_iemnet_chunk*chunk)
+{
+ unsigned int i=0;
+ for(i=0; i<nsr; i++) {
+ tcpserver_send_bytes_client(x, sr[i], i, chunk);
+ }
+}
/* broadcasts a message to all connected clients but the given one */
-static void tcpserver_send_butclient(t_tcpserver *x, int but, int argc, t_atom *argv)
+static void tcpserver_send_butclient(t_tcpserver *x, unsigned int but,
+ int argc, t_atom *argv)
{
- int client=0;
- t_iemnet_chunk*chunk=iemnet__chunk_create_list(argc, argv);
+ unsigned int client=0;
+ t_iemnet_chunk*chunk=NULL;
+ t_tcpserver_socketreceiver**sr=NULL;
+ if(!x || !x->x_nconnections) {
+ return;
+ }
- /* enumerate through the clients and send each the message */
- for(client = 0; client < x->x_nconnections; client++) /* check if connection exists */
- {
- /* socket exists for this client */
- if(client!=but)tcpserver_send_bytes(x, client, chunk);
- }
+ chunk=iemnet__chunk_create_list(argc, argv);
+ sr=(t_tcpserver_socketreceiver**)calloc(x->x_nconnections,
+ sizeof(t_tcpserver_socketreceiver*));
+
+ for(client=0; client<x->x_nconnections; client++) {
+ sr[client]=x->x_sr[client];
+ }
+
+ if(but<x->x_nconnections) {
+ sr[but]=NULL;
+ }
+
+ tcpserver_send_bytes_clients(x, sr, x->x_nconnections, chunk);
+
+ free(sr);
iemnet__chunk_destroy(chunk);
}
/* sends a message to a given client */
-static void tcpserver_send_toclient(t_tcpserver *x, int client, int argc, t_atom *argv)
+static void tcpserver_send_toclient(t_tcpserver *x, unsigned int client,
+ int argc, t_atom *argv)
{
t_iemnet_chunk*chunk=iemnet__chunk_create_list(argc, argv);
tcpserver_send_bytes(x, client, chunk);
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 */
-static void tcpserver_send_client(t_tcpserver *x, t_symbol *s, int argc, t_atom *argv)
+static void tcpserver_send_client(t_tcpserver *x, t_symbol *s, int argc,
+ t_atom *argv)
{
int client=0;
-
- if (argc > 0)
- {
- client=tcpserver_fixindex(x, atom_getint(argv));
- if(client<0)return;
- if(argc==1) {
- tcpserver_info_client(x, client);
- } else {
- tcpserver_send_toclient(x, client, argc-1, argv+1);
- }
+
+ if (argc > 0) {
+ client=tcpserver_fixindex(x, atom_getint(argv));
+ if(client<0) {
return;
}
- else
- {
- for(client=0; client<x->x_nconnections; client++)
- tcpserver_info_client(x, client);
+ if(argc==1) {
+ tcpserver_info_client(x, client);
+ } else {
+ tcpserver_send_toclient(x, client, argc-1, argv+1);
+ }
+ return;
+ } else {
+ unsigned int client;
+ for(client=0; client<x->x_nconnections; client++) {
+ tcpserver_info_client(x, client);
}
+ }
}
/* broadcasts a message to all connected clients */
-static void tcpserver_broadcast(t_tcpserver *x, t_symbol *s, int argc, t_atom *argv)
+static void tcpserver_broadcast(t_tcpserver *x, t_symbol *s, int argc,
+ t_atom *argv)
{
- int client;
- t_iemnet_chunk*chunk=iemnet__chunk_create_list(argc, argv);
+ unsigned int client=0;
+ t_iemnet_chunk*chunk=NULL;
+ t_tcpserver_socketreceiver**sr=NULL;
+ if(!x || !x->x_nconnections) {
+ return;
+ }
- /* enumerate through the clients and send each the message */
- for(client = 0; client < x->x_nconnections; client++) /* check if connection exists */
- {
- /* socket exists for this client */
- tcpserver_send_bytes(x, client, chunk);
- }
+ chunk=iemnet__chunk_create_list(argc, argv);
+ sr=(t_tcpserver_socketreceiver**)calloc(x->x_nconnections,
+ sizeof(t_tcpserver_socketreceiver*));
+
+ for(client=0; client<x->x_nconnections; client++) {
+ sr[client]=x->x_sr[client];
+ }
+
+ tcpserver_send_bytes_clients(x, sr, x->x_nconnections, chunk);
+
+ free(sr);
iemnet__chunk_destroy(chunk);
}
/* broadcasts a message to all connected clients */
-static void tcpserver_broadcastbut(t_tcpserver *x, t_symbol *s, int argc, t_atom *argv)
+static void tcpserver_broadcastbut(t_tcpserver *x, t_symbol *s, int argc,
+ t_atom *argv)
{
int but=-1;
//int client=0;
@@ -329,32 +381,48 @@ static void tcpserver_broadcastbut(t_tcpserver *x, t_symbol *s, int argc, t_atom
if(argc<2) {
return;
}
- if((but=tcpserver_fixindex(x, atom_getint(argv)))<0)return;
+ if((but=tcpserver_fixindex(x, atom_getint(argv)))<0) {
+ return;
+ }
tcpserver_send_butclient(x, but, argc-1, argv+1);
}
-static void tcpserver_defaultsend(t_tcpserver *x, t_symbol *s, int argc, t_atom *argv)
+static void tcpserver_defaultsend(t_tcpserver *x, t_symbol *s, int argc,
+ t_atom *argv)
{
int client=-1;
int sockfd=x->x_defaulttarget;
- if(0==sockfd)
- tcpserver_broadcast(x, s, argc, argv);
- else if(sockfd>0) {
+ if(sockfd>0) {
client=tcpserver_socket2index(x, sockfd);
- tcpserver_send_toclient(x, client, argc, argv);
+ if(client>=0) {
+ tcpserver_send_toclient(x, client, argc, argv);
+ return;
+ }
+ pd_error(x, "[%s] illegal socket %d, switching to broadcast mode", objName,
+ sockfd);
+ x->x_defaulttarget=0;
} else if(sockfd<0) {
client=tcpserver_socket2index(x, -sockfd);
- tcpserver_send_butclient(x, client, argc, argv);
+ if(client>=0) {
+ tcpserver_send_butclient(x, client, argc, argv);
+ return;
+ }
+ pd_error(x, "[%s] illegal !ocket %d, switching to broadcast mode", objName,
+ sockfd);
+ x->x_defaulttarget=0;
}
+
+ tcpserver_broadcast(x, s, argc, argv);
}
static void tcpserver_defaulttarget(t_tcpserver *x, t_floatarg f)
{
int sockfd=0;
int rawclient=f;
- int client=(rawclient<0)?(-rawclient):rawclient;
+ 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));
+ error("[%s] target %d out of range [0..%d]", objName, client,
+ (int)(x->x_nconnections));
return;
}
@@ -363,7 +431,9 @@ static void tcpserver_defaulttarget(t_tcpserver *x, t_floatarg f)
sockfd=x->x_sr[client-1]->sr_fd;
}
- if(rawclient<0)sockfd=-sockfd;
+ if(rawclient<0) {
+ sockfd=-sockfd;
+ }
x->x_defaulttarget=sockfd;
}
@@ -376,43 +446,42 @@ static void tcpserver_targetsocket(t_tcpserver *x, t_floatarg f)
/* send message to client using socket number */
-static void tcpserver_send_socket(t_tcpserver *x, t_symbol *s, int argc, t_atom *argv)
+static void tcpserver_send_socket(t_tcpserver *x, t_symbol *s, int argc,
+ t_atom *argv)
{
int client = -1;
t_iemnet_chunk*chunk=NULL;
if(argc) {
client = tcpserver_socket2index(x, atom_getint(argv));
- if(client<0)return;
+ if(client<0) {
+ return;
+ }
} else {
pd_error(x, "%s_send: no socket specified", objName);
return;
}
/* get socket number of connection (first element in list) */
- if(argc && argv->a_type == A_FLOAT)
- {
- int sockfd=atom_getint(argv);
- client = tcpserver_socket2index(x, sockfd);
- if(client < 0)
- {
- post("%s_send: no connection on socket %d", objName, sockfd);
- return;
- }
- }
- else
- {
- post("%s_send: no socket specified", objName);
+ if(argc && argv->a_type == A_FLOAT) {
+ int sockfd=atom_getint(argv);
+ client = tcpserver_socket2index(x, sockfd);
+ if(client < 0) {
+ post("%s_send: no connection on socket %d", objName, sockfd);
return;
}
-
+ } else {
+ post("%s_send: no socket specified", objName);
+ return;
+ }
+
chunk=iemnet__chunk_create_list(argc-1, argv+1);
tcpserver_send_bytes(x, client, chunk);
iemnet__chunk_destroy(chunk);
}
-static void tcpserver_disconnect(t_tcpserver *x, int client)
+static void tcpserver_disconnect(t_tcpserver *x, unsigned int client)
{
- int k;
+ unsigned int k;
DEBUG("disconnect %x %d", x, client);
tcpserver_info_connection(x, x->x_sr[client]);
@@ -420,10 +489,9 @@ static void tcpserver_disconnect(t_tcpserver *x, int client)
x->x_sr[client]=NULL;
/* rearrange list now: move entries to close the gap */
- for(k = client; k < x->x_nconnections; k++)
- {
- x->x_sr[k] = x->x_sr[k + 1];
- }
+ for(k = client; k < x->x_nconnections; k++) {
+ x->x_sr[k] = x->x_sr[k + 1];
+ }
x->x_sr[k + 1]=NULL;
x->x_nconnections--;
@@ -437,7 +505,9 @@ static void tcpserver_disconnect_client(t_tcpserver *x, t_floatarg fclient)
{
int client = tcpserver_fixindex(x, fclient);
- if(client<0)return;
+ if(client<0) {
+ return;
+ }
tcpserver_disconnect(x, client);
}
@@ -446,8 +516,9 @@ static void tcpserver_disconnect_client(t_tcpserver *x, t_floatarg fclient)
static void tcpserver_disconnect_socket(t_tcpserver *x, t_floatarg fsocket)
{
int id=tcpserver_socket2index(x, (int)fsocket);
- if(id>=0)
+ if(id>=0) {
tcpserver_disconnect_client(x, id+1);
+ }
}
@@ -455,23 +526,28 @@ static void tcpserver_disconnect_socket(t_tcpserver *x, t_floatarg fsocket)
/* disconnect a client by socket */
static void tcpserver_disconnect_all(t_tcpserver *x)
{
- int id=x->x_nconnections;
- while(--id>=0) {
+ unsigned int id;
+ for(id=0; id<x->x_nconnections; id++) {
tcpserver_disconnect(x, id);
}
}
/* ---------------- main tcpserver (receive) stuff --------------------- */
-static void tcpserver_receive_callback(void *y0,
- t_iemnet_chunk*c) {
+static void tcpserver_receive_callback(void *y0,
+ t_iemnet_chunk*c)
+{
t_tcpserver_socketreceiver *y=(t_tcpserver_socketreceiver*)y0;
t_tcpserver*x=NULL;
- if(NULL==y || NULL==(x=y->sr_owner))return;
-
+ if(NULL==y || NULL==(x=y->sr_owner)) {
+ return;
+ }
+
if(c) {
tcpserver_info_connection(x, y);
- x->x_floatlist=iemnet__chunk2list(c, x->x_floatlist); // get's destroyed in the dtor
- iemnet__streamout(x->x_msgout, x->x_floatlist->argc, x->x_floatlist->argv, x->x_serialize);
+ x->x_floatlist=iemnet__chunk2list(c,
+ x->x_floatlist); // get's destroyed in the dtor
+ iemnet__streamout(x->x_msgout, x->x_floatlist->argc, x->x_floatlist->argv,
+ x->x_serialize);
} else {
// disconnected
int sockfd=y->sr_fd;
@@ -486,25 +562,33 @@ static void tcpserver_connectpoll(t_tcpserver *x)
{
struct sockaddr_in incomer_address;
socklen_t sockaddrl = sizeof( struct sockaddr );
- int fd = accept(x->x_connectsocket, (struct sockaddr*)&incomer_address, &sockaddrl);
+ int fd = accept(x->x_connectsocket,
+ (struct sockaddr*)&incomer_address, &sockaddrl);
int i;
- if (fd < 0) post("%s: accept failed", objName);
- else
- {
- t_tcpserver_socketreceiver *y = tcpserver_socketreceiver_new((void *)x, fd, &incomer_address);
- if (!y)
- {
- sys_closesocket(fd);
- return;
- }
- x->x_nconnections++;
- i = x->x_nconnections - 1;
- x->x_sr[i] = y;
-
- tcpserver_info_connection(x, y);
+ if (fd < 0) {
+ post("%s: accept failed", objName);
+ } 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__closesocket(fd);
}
+
+ y = tcpserver_socketreceiver_new((void *)x, fd, &incomer_address);
+ if (!y) {
+ iemnet__closesocket(fd);
+ return;
+ }
+ x->x_nconnections++;
+ i = x->x_nconnections - 1;
+ x->x_sr[i] = y;
+
+ tcpserver_info_connection(x, y);
+ }
+
outlet_float(x->x_connectout, x->x_nconnections);
}
@@ -515,6 +599,8 @@ static void tcpserver_port(t_tcpserver*x, t_floatarg fportno)
struct sockaddr_in server;
socklen_t serversize=sizeof(server);
int sockfd = x->x_connectsocket;
+ memset(&server, 0, sizeof(server));
+
SETFLOAT(ap, -1);
if(x->x_port == portno) {
return;
@@ -523,14 +609,16 @@ static void tcpserver_port(t_tcpserver*x, t_floatarg fportno)
/* cleanup any open ports */
if(sockfd>=0) {
sys_rmpollfn(sockfd);
- sys_closesocket(sockfd);
+ iemnet__closesocket(sockfd);
x->x_connectsocket=-1;
x->x_port=-1;
}
-
sockfd = socket(AF_INET, SOCK_STREAM, 0);
-
+ if(sockfd<0) {
+ sys_sockerror("[tcpserver]: cannot create TCP/IP socket");
+ return;
+ }
server.sin_family = AF_INET;
@@ -540,27 +628,24 @@ static void tcpserver_port(t_tcpserver*x, t_floatarg fportno)
/* 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_statout, gensym("port"), 1, ap);
- return;
- }
+ if (bind(sockfd, (struct sockaddr *)&server, serversize) < 0) {
+ sys_sockerror("tcpserver: bind");
+ iemnet__closesocket(sockfd);
+ outlet_anything(x->x_statout, gensym("port"), 1, ap);
+ return;
+ }
/* streaming protocol */
- if (listen(sockfd, 5) < 0)
- {
- sys_sockerror("tcpserver: listen");
- sys_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
- }
+ if (listen(sockfd, 5) < 0) {
+ sys_sockerror("tcpserver: 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
+ }
x->x_connectsocket = sockfd;
x->x_port = portno;
@@ -576,7 +661,8 @@ static void tcpserver_port(t_tcpserver*x, t_floatarg fportno)
outlet_anything(x->x_statout, gensym("port"), 1, ap);
}
-static void tcpserver_serialize(t_tcpserver *x, t_floatarg doit) {
+static void tcpserver_serialize(t_tcpserver *x, t_floatarg doit)
+{
x->x_serialize=doit;
}
@@ -589,10 +675,12 @@ static void *tcpserver_new(t_floatarg fportno)
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_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_statout = outlet_new(&x->x_obj,
+ 0);/* 5th outlet for everything else */
x->x_serialize=1;
@@ -600,14 +688,13 @@ static void *tcpserver_new(t_floatarg fportno)
x->x_port = -1;
x->x_nconnections = 0;
- for(i = 0; i < MAX_CONNECT; i++)
- {
- x->x_sr[i] = NULL;
- }
+ for(i = 0; i < MAX_CONNECT; i++) {
+ x->x_sr[i] = NULL;
+ }
x->x_defaulttarget=0;
-
-
+
+
x->x_floatlist=iemnet__floatlist_create(1024);
tcpserver_port(x, fportno);
@@ -619,46 +706,60 @@ static void tcpserver_free(t_tcpserver *x)
{
int i;
- for(i = 0; i < MAX_CONNECT; i++)
- {
- if (NULL!=x->x_sr[i]) {
- DEBUG("[%s] free %x", objName, x);
- tcpserver_socketreceiver_free(x->x_sr[i]);
- x->x_sr[i]=NULL;
- }
+ for(i = 0; i < MAX_CONNECT; i++) {
+ if (NULL!=x->x_sr[i]) {
+ DEBUG("[%s] free %x", objName, x);
+ tcpserver_socketreceiver_free(x->x_sr[i]);
+ x->x_sr[i]=NULL;
}
- if (x->x_connectsocket >= 0)
- {
- sys_rmpollfn(x->x_connectsocket);
- sys_closesocket(x->x_connectsocket);
- }
- if(x->x_floatlist)iemnet__floatlist_destroy(x->x_floatlist);x->x_floatlist=NULL;
+ }
+ if (x->x_connectsocket >= 0) {
+ sys_rmpollfn(x->x_connectsocket);
+ iemnet__closesocket(x->x_connectsocket);
+ }
+ if(x->x_floatlist) {
+ iemnet__floatlist_destroy(x->x_floatlist);
+ }
+ x->x_floatlist=NULL;
}
IEMNET_EXTERN void tcpserver_setup(void)
{
- if(!iemnet__register(objName))return;
+ if(!iemnet__register(objName)) {
+ return;
+ }
- tcpserver_class = class_new(gensym(objName),(t_newmethod)tcpserver_new, (t_method)tcpserver_free,
+ tcpserver_class = class_new(gensym(objName),(t_newmethod)tcpserver_new,
+ (t_method)tcpserver_free,
sizeof(t_tcpserver), 0, A_DEFFLOAT, 0);
- class_addmethod(tcpserver_class, (t_method)tcpserver_disconnect_client, gensym("disconnectclient"), A_DEFFLOAT, 0);
- class_addmethod(tcpserver_class, (t_method)tcpserver_disconnect_socket, gensym("disconnectsocket"), A_DEFFLOAT, 0);
- class_addmethod(tcpserver_class, (t_method)tcpserver_disconnect_all, gensym("disconnect"), 0);
-
- class_addmethod(tcpserver_class, (t_method)tcpserver_send_socket, gensym("send"), A_GIMME, 0);
- class_addmethod(tcpserver_class, (t_method)tcpserver_send_client, gensym("client"), A_GIMME, 0);
-
- 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_addmethod(tcpserver_class, (t_method)tcpserver_targetsocket, gensym("targetsocket"), A_DEFFLOAT, 0);
+ class_addmethod(tcpserver_class, (t_method)tcpserver_disconnect_client,
+ gensym("disconnectclient"), A_DEFFLOAT, 0);
+ class_addmethod(tcpserver_class, (t_method)tcpserver_disconnect_socket,
+ gensym("disconnectsocket"), A_DEFFLOAT, 0);
+ class_addmethod(tcpserver_class, (t_method)tcpserver_disconnect_all,
+ gensym("disconnect"), 0);
+
+ class_addmethod(tcpserver_class, (t_method)tcpserver_send_socket,
+ gensym("send"), A_GIMME, 0);
+ class_addmethod(tcpserver_class, (t_method)tcpserver_send_client,
+ gensym("client"), A_GIMME, 0);
+
+ 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_addmethod(tcpserver_class, (t_method)tcpserver_targetsocket,
+ 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);
+ class_addmethod(tcpserver_class, (t_method)tcpserver_serialize,
+ gensym("serialize"), A_FLOAT, 0);
- class_addmethod(tcpserver_class, (t_method)tcpserver_port, gensym("port"), A_DEFFLOAT, 0);
+ class_addmethod(tcpserver_class, (t_method)tcpserver_port, gensym("port"),
+ A_DEFFLOAT, 0);
class_addbang (tcpserver_class, (t_method)tcpserver_info);
DEBUGMETHOD(tcpserver_class);