From c5e0079ae1323ad4c35d28f83ce732bb3820c46a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?IOhannes=20m=20zm=C3=B6lnig?= Date: Mon, 31 Aug 2015 22:11:51 +0000 Subject: un-threaded receive svn path=/trunk/externals/iem/iemnet/; revision=17543 --- udpserver.c | 479 +++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 280 insertions(+), 199 deletions(-) (limited to 'udpserver.c') diff --git a/udpserver.c b/udpserver.c index 93bf10b..df4b389 100644 --- a/udpserver.c +++ b/udpserver.c @@ -2,7 +2,7 @@ * * listens on a UDP-socket for bi-directional communication * - * 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 */ @@ -22,9 +22,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/ */ /* */ /* ---------------------------------------------------------------------------- */ @@ -32,6 +31,7 @@ #include "iemnet.h" #include #include +#include #define MAX_CONNECT 32 /* maximum number of connections */ @@ -40,8 +40,7 @@ static t_class *udpserver_class; static const char objName[] = "udpserver"; -typedef struct _udpserver_sender -{ +typedef struct _udpserver_sender { struct _udpserver *sr_owner; long sr_host; @@ -50,8 +49,7 @@ typedef struct _udpserver_sender t_iemnet_sender*sr_sender; } t_udpserver_sender; -typedef struct _udpserver -{ +typedef struct _udpserver { t_object x_obj; t_outlet *x_msgout; t_outlet *x_connectout; @@ -62,19 +60,24 @@ typedef struct _udpserver t_udpserver_sender *x_sr[MAX_CONNECT]; /* socket per connection */ t_int x_nconnections; - t_int x_connectsocket; /* socket waiting for new connections */ + t_int + x_connectsocket; /* socket waiting for new connections */ t_int x_port; - unsigned char x_accept; /* whether we accept new connections or not */ + unsigned char + x_accept; /* whether we accept new connections or not */ - int x_defaulttarget; /* the default connection to send to; 0=broadcast; >0 use this client; <0 exclude this client */ + int + x_defaulttarget; /* the default connection to send to; 0=broadcast; >0 use this client; <0 exclude this client */ t_iemnet_receiver *x_receiver; t_iemnet_floatlist *x_floatlist; } t_udpserver; -static t_udpserver_sender *udpserver_sender_new(t_udpserver *owner, unsigned long host, unsigned short port) +static t_udpserver_sender *udpserver_sender_new(t_udpserver *owner, + unsigned long host, unsigned short port) { - t_udpserver_sender *x = (t_udpserver_sender *)malloc(sizeof(t_udpserver_sender)); + t_udpserver_sender *x = (t_udpserver_sender *)malloc(sizeof( + t_udpserver_sender)); if(NULL==x) { error("%s_sender: unable to allocate %d bytes", objName, (int)sizeof(*x)); return NULL; @@ -87,7 +90,7 @@ static t_udpserver_sender *udpserver_sender_new(t_udpserver *owner, unsigned lo x->sr_host=host; //ntohl(addr->sin_addr.s_addr); x->sr_port=port; //ntohs(addr->sin_port); - x->sr_sender=iemnet__sender_create(sockfd); + x->sr_sender=iemnet__sender_create(sockfd, NULL, NULL, 0); } return (x); } @@ -95,39 +98,40 @@ static t_udpserver_sender *udpserver_sender_new(t_udpserver *owner, unsigned lo static void udpserver_sender_free(t_udpserver_sender *x) { DEBUG("freeing %x", x); - if (x != NULL) - { - int sockfd=x->sr_fd; - t_iemnet_sender*sender=x->sr_sender; - - x->sr_owner=NULL; - x->sr_sender=NULL; + if (x != NULL) { + int sockfd=x->sr_fd; + t_iemnet_sender*sender=x->sr_sender; - x->sr_fd=-1; + x->sr_owner=NULL; + x->sr_sender=NULL; - free(x); + x->sr_fd=-1; - if(sender) iemnet__sender_destroy(sender); + free(x); - sys_closesocket(sockfd); + if(sender) { + iemnet__sender_destroy(sender, 0); } + + iemnet__closesocket(sockfd); + } + /* coverity[pass_freed_arg]: this is merely for debugging printout */ DEBUG("freeed %x", x); } -static t_udpserver_sender* udpserver_sender_copy(t_udpserver_sender*x) { +static t_udpserver_sender* udpserver_sender_copy(t_udpserver_sender*x) +{ return udpserver_sender_new(x->sr_owner,x->sr_host, x->sr_port); } static int udpserver_socket2index(t_udpserver*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; - } + for(i = 0; i < x->x_nconnections; i++) { /* check if connection exists */ + if(x->x_sr[i]->sr_fd == sockfd) { + return i; } + } return -1; } @@ -137,35 +141,42 @@ static int udpserver_socket2index(t_udpserver*x, int sockfd) */ static int udpserver_fixindex(t_udpserver*x, int client) { - if(x->x_nconnections <= 0) - { - pd_error(x, "[%s]: no clients connected", objName); - 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; - } + 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); } /* returns 1 if addr1==addr2, 0 otherwise */ -static int equal_addr(unsigned long host1, unsigned short port1, unsigned long host2, unsigned short port2) { +static int equal_addr(unsigned long host1, unsigned short port1, + unsigned long host2, unsigned short port2) +{ return ( - ((port1 == port2) && - (host1 == host2)) - ); + ((port1 == port2) && + (host1 == host2)) + ); } -static int udpserver__find_sender(t_udpserver*x, unsigned long host, unsigned short port) { +static int udpserver__find_sender(t_udpserver*x, unsigned long host, + unsigned short port) +{ int i=0; for(i=0; ix_nconnections; i++) { - if(NULL==x->x_sr[i])return -1; - if(equal_addr(host, port, x->x_sr[i]->sr_host, x->x_sr[i]->sr_port))return i; + if(NULL==x->x_sr[i]) { + return -1; + } + if(equal_addr(host, port, x->x_sr[i]->sr_host, x->x_sr[i]->sr_port)) { + return i; + } } return -1; } @@ -175,11 +186,13 @@ static int udpserver__find_sender(t_udpserver*x, unsigned long host, unsigned s * if not, add it to the list of registered senders */ static t_udpserver_sender* udpserver_sender_add(t_udpserver*x, - unsigned long host, unsigned short port ) + unsigned long host, unsigned short port ) { int id=-1; - if(!x->x_accept)return NULL; + if(!x->x_accept) { + return NULL; + } id=udpserver__find_sender(x, host, port); DEBUG("%X:%d -> %d", host, port, id); @@ -217,9 +230,10 @@ static t_udpserver_sender* udpserver_sender_add(t_udpserver*x, return NULL; } -static void udpserver_sender_remove(t_udpserver*x, int id) { - if(id>=0 && idx_nconnections && x->x_sr[id]) { - int i; +static void udpserver_sender_remove(t_udpserver*x, unsigned int id) +{ + if(idx_nconnections && x->x_sr[id]) { + unsigned int i; t_udpserver_sender* sdr=x->x_sr[id]; udpserver_sender_free(sdr); @@ -235,15 +249,13 @@ static void udpserver_sender_remove(t_udpserver*x, int id) { } - - /* ---------------- udpserver info ---------------------------- */ static void udpserver_info_client(t_udpserver *x, int client) { // "client " // "bufsize " static t_atom output_atom[4]; - if(x&&x->x_sr&&x->x_sr[client]) { + if(x&&clientx_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; @@ -256,8 +268,8 @@ static void udpserver_info_client(t_udpserver *x, int client) (unsigned char)((address & 0xFF000000)>>24), (unsigned char)((address & 0x0FF0000)>>16), (unsigned char)((address & 0x0FF00)>>8), - (unsigned char)((address & 0x0FF)) - ); + (unsigned char)((address & 0x0FF)) + ); hostname[MAXPDSTRING-1]=0; SETFLOAT (output_atom+0, client+1); @@ -275,7 +287,8 @@ static void udpserver_info_client(t_udpserver *x, int client) } -static void udpserver_info(t_udpserver *x) { +static void udpserver_info(t_udpserver *x) +{ static t_atom output_atom[4]; int sockfd=x->x_connectsocket; @@ -287,10 +300,11 @@ static void udpserver_info(t_udpserver *x) { error("[%s] no valid sock", objName); } - if(x->x_port<=0) { struct sockaddr_in server; socklen_t serversize=sizeof(server); + memset(&server, 0, sizeof(server)); + if(!getsockname(sockfd, (struct sockaddr *)&server, &serversize)) { x->x_port=ntohs(server.sin_port); port=x->x_port; @@ -311,16 +325,20 @@ static void udpserver_info_connection(t_udpserver *x, t_udpserver_sender*y) } /* ---------------- main udpserver (send) stuff --------------------- */ -static void udpserver_disconnect_socket(t_udpserver *x, t_floatarg fsocket); -static void udpserver_send_bytes(t_udpserver*x, int client, t_iemnet_chunk*chunk) +static void udpserver_disconnect_socket(t_udpserver *x, + t_floatarg fsocket); +static void udpserver_send_bytes(t_udpserver*x, unsigned 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(clientx_sr[client]); + } + if(x && clientx_sr[client]) { t_atom output_atom[3]; int size=0; - t_iemnet_sender*sender=sender=x->x_sr[client]->sr_sender; + t_iemnet_sender*sender=x->x_sr[client]->sr_sender; int sockfd = x->x_sr[client]->sr_fd; chunk->addr=x->x_sr[client]->sr_host; @@ -333,7 +351,7 @@ static void udpserver_send_bytes(t_udpserver*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! @@ -345,21 +363,25 @@ static void udpserver_send_bytes(t_udpserver*x, int client, t_iemnet_chunk*chunk /* broadcasts a message to all connected clients but the given one */ -static void udpserver_send_butclient(t_udpserver *x, int but, int argc, t_atom *argv) +static void udpserver_send_butclient(t_udpserver *x, unsigned int but, + int argc, t_atom *argv) { - int client=0; + unsigned int client=0; t_iemnet_chunk*chunk=iemnet__chunk_create_list(argc, argv); /* 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)udpserver_send_bytes(x, client, chunk); + for(client = 0; client < x->x_nconnections; + client++) { /* check if connection exists */ + /* socket exists for this client */ + if(client!=but) { + udpserver_send_bytes(x, client, chunk); } + } iemnet__chunk_destroy(chunk); } /* sends a message to a given client */ -static void udpserver_send_toclient(t_udpserver *x, int client, int argc, t_atom *argv) +static void udpserver_send_toclient(t_udpserver *x, unsigned int client, + int argc, t_atom *argv) { t_iemnet_chunk*chunk=iemnet__chunk_create_list(argc, argv); udpserver_send_bytes(x, client, chunk); @@ -371,71 +393,91 @@ static void udpserver_send_toclient(t_udpserver *x, int client, int argc, t_atom /* 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 udpserver_send_client(t_udpserver *x, t_symbol *s, int argc, t_atom *argv) +static void udpserver_send_client(t_udpserver *x, t_symbol *s, int argc, + t_atom *argv) { int client=0; - if (argc > 0) - { - client=udpserver_fixindex(x, atom_getint(argv)); - if(client<0)return; - if(argc==1) { - udpserver_info_client(x, client); - } else { - udpserver_send_toclient(x, client, argc-1, argv+1); - } + if (argc > 0) { + client=udpserver_fixindex(x, atom_getint(argv)); + if(client<0) { return; } - else - { - for(client=0; clientx_nconnections; client++) - udpserver_info_client(x, client); + if(argc==1) { + udpserver_info_client(x, client); + } else { + udpserver_send_toclient(x, client, argc-1, argv+1); + } + return; + } else { + for(client=0; clientx_nconnections; client++) { + udpserver_info_client(x, client); } + } } /* broadcasts a message to all connected clients */ -static void udpserver_broadcast(t_udpserver *x, t_symbol *s, int argc, t_atom *argv) +static void udpserver_broadcast(t_udpserver *x, t_symbol *s, int argc, + t_atom *argv) { - int client; + unsigned int client; t_iemnet_chunk*chunk=iemnet__chunk_create_list(argc, argv); DEBUG("broadcasting to %d clients", x->x_nconnections); /* 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 */ - udpserver_send_bytes(x, client, chunk); - } + for(client = 0; client < x->x_nconnections; + client++) { /* check if connection exists */ + /* socket exists for this client */ + udpserver_send_bytes(x, client, chunk); + } iemnet__chunk_destroy(chunk); } /* broadcasts a message to all connected clients */ -static void udpserver_broadcastbut(t_udpserver *x, t_symbol *s, int argc, t_atom *argv) +static void udpserver_broadcastbut(t_udpserver *x, t_symbol *s, int argc, + t_atom *argv) { - int but=-1; + int but; if(argc<2) { return; } - if((but=udpserver_fixindex(x, atom_getint(argv)))<0)return; + if((but=udpserver_fixindex(x, atom_getint(argv)))<0) { + return; + } udpserver_send_butclient(x, but, argc-1, argv+1); } -static void udpserver_defaultsend(t_udpserver *x, t_symbol *s, int argc, t_atom *argv) +static void udpserver_defaultsend(t_udpserver *x, t_symbol *s, int argc, + t_atom *argv) { int client=-1; int sockfd=x->x_defaulttarget; DEBUG("sending to sockfd: %d", sockfd); - if(0==sockfd) - udpserver_broadcast(x, s, argc, argv); - else if(sockfd>0) { + if(sockfd>0) { client=udpserver_socket2index(x, sockfd); - udpserver_send_toclient(x, client, argc, argv); + if(client<0) { + pd_error(x, "[%s] illegal socket %d, switching to broadcast mode", objName, + sockfd); + x->x_defaulttarget=0; + } else { + udpserver_send_toclient(x, client, argc, argv); + return; + } } else if(sockfd<0) { client=udpserver_socket2index(x, -sockfd); - udpserver_send_butclient(x, client, argc, argv); + if(client<0) { + pd_error(x, "[%s] illegal !socket %d, switching to broadcast mode", + objName, sockfd); + x->x_defaulttarget=0; + } else { + udpserver_send_butclient(x, client, argc, argv); + return; + } } + + udpserver_broadcast(x, s, argc, argv); } static void udpserver_defaulttarget(t_udpserver *x, t_floatarg f) { @@ -444,7 +486,8 @@ static void udpserver_defaulttarget(t_udpserver *x, t_floatarg f) 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; } @@ -453,7 +496,9 @@ static void udpserver_defaulttarget(t_udpserver *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; } @@ -466,55 +511,62 @@ static void udpserver_targetsocket(t_udpserver *x, t_floatarg f) /* send message to client using socket number */ -static void udpserver_send_socket(t_udpserver *x, t_symbol *s, int argc, t_atom *argv) +static void udpserver_send_socket(t_udpserver *x, t_symbol *s, int argc, + t_atom *argv) { int client = -1; t_iemnet_chunk*chunk=NULL; if(argc) { client = udpserver_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 = udpserver_socket2index(x, sockfd); - if(client < 0) - { - error("[%s]: no connection on socket %d", objName, sockfd); - return; - } - } - else - { - error("[%s]: no socket specified", objName); + if(argc && argv->a_type == A_FLOAT) { + int sockfd=atom_getint(argv); + client = udpserver_socket2index(x, sockfd); + if(client < 0) { + error("[%s]: no connection on socket %d", objName, sockfd); return; } + } else { + error("[%s]: no socket specified", objName); + return; + } chunk=iemnet__chunk_create_list(argc-1, argv+1); udpserver_send_bytes(x, client, chunk); iemnet__chunk_destroy(chunk); } -static void udpserver_disconnect(t_udpserver *x, int client) +static void udpserver_disconnect(t_udpserver *x, unsigned int client) { - t_udpserver_sender*sdr; + t_udpserver_sender*sdr=NULL; int conns; DEBUG("disconnect %x %d", x, client); - if(client<0 || client >= x->x_nconnections)return; + if(client >= x->x_nconnections) { + return; + } - sdr=udpserver_sender_copy(x->x_sr[client]); + sdr = (t_udpserver_sender *)calloc(1, sizeof(t_udpserver_sender)); + if(sdr) { + sdr->sr_host=x->x_sr[client]->sr_host; + sdr->sr_port=x->x_sr[client]->sr_port; + } udpserver_sender_remove(x, client); conns=x->x_nconnections; - - udpserver_info_connection(x, sdr); + if(sdr) { + udpserver_info_connection(x, sdr); + free(sdr); + } outlet_float(x->x_connectout, conns); } @@ -524,7 +576,9 @@ static void udpserver_disconnect_client(t_udpserver *x, t_floatarg fclient) { int client = udpserver_fixindex(x, fclient); - if(client<0)return; + if(client<0) { + return; + } udpserver_disconnect(x, client); } @@ -533,8 +587,9 @@ static void udpserver_disconnect_client(t_udpserver *x, t_floatarg fclient) static void udpserver_disconnect_socket(t_udpserver *x, t_floatarg fsocket) { int id=udpserver_socket2index(x, (int)fsocket); - if(id>=0) + if(id>=0) { udpserver_disconnect_client(x, id+1); + } } @@ -542,22 +597,26 @@ static void udpserver_disconnect_socket(t_udpserver *x, t_floatarg fsocket) /* disconnect a client by socket */ static void udpserver_disconnect_all(t_udpserver *x) { - int id=x->x_nconnections; - while(--id>=0) { + unsigned int id; + for(id=0; idx_nconnections; id++) { udpserver_disconnect(x, id); } } /* whether we should accept new connections */ -static void udpserver_accept(t_udpserver *x, t_float f) { +static void udpserver_accept(t_udpserver *x, t_float f) +{ x->x_accept=(unsigned char)f; } /* ---------------- main udpserver (receive) stuff --------------------- */ -static void udpserver_receive_callback(void *y, t_iemnet_chunk*c) { +static void udpserver_receive_callback(void *y, t_iemnet_chunk*c) +{ t_udpserver*x=(t_udpserver*)y; - if(NULL==y)return; + if(NULL==y) { + return; + } if(c) { int conns = x->x_nconnections; @@ -567,13 +626,15 @@ static void udpserver_receive_callback(void *y, t_iemnet_chunk*c) { DEBUG("added new sender from %d", c->port); if(sdr) { udpserver_info_connection(x, sdr); - x->x_floatlist=iemnet__chunk2list(c, x->x_floatlist); // gets destroyed in the dtor + x->x_floatlist=iemnet__chunk2list(c, + x->x_floatlist); // gets destroyed in the dtor /* here we might have a reentrancy problem */ if(conns!=x->x_nconnections) { outlet_float(x->x_connectout, x->x_nconnections); } - outlet_list(x->x_msgout, gensym("list"), x->x_floatlist->argc, x->x_floatlist->argv); + outlet_list(x->x_msgout, gensym("list"), x->x_floatlist->argc, + x->x_floatlist->argv); } } else { // disconnection never happens with a connectionless protocol like UDP @@ -592,28 +653,28 @@ static void udpserver_connectpoll(t_udpserver *x) // TODO: provide a way to not accept connection // idea: add a message "accept $1" to turn off/on acceptance of new connections - fd = accept(x->x_connectsocket, (struct sockaddr*)&incomer_address, &sockaddrl); + fd = accept(x->x_connectsocket, (struct sockaddr*)&incomer_address, + &sockaddrl); bug("connectpoll"); - if (fd < 0) error("[%s] accept failed", objName); - else - { - unsigned long host = ntohl(incomer_address.sin_addr.s_addr); - unsigned short port = ntohs(incomer_address.sin_port); - - t_udpserver_sender *y = udpserver_sender_new(x, host, port); - if (!y) - { - sys_closesocket(fd); - return; - } - x->x_nconnections++; - i = x->x_nconnections - 1; - x->x_sr[i] = y; + if (fd < 0) { + error("[%s] accept failed", objName); + } else { + unsigned long host = ntohl(incomer_address.sin_addr.s_addr); + unsigned short port = ntohs(incomer_address.sin_port); - udpserver_info_connection(x, y); + t_udpserver_sender *y = udpserver_sender_new(x, host, port); + if (!y) { + iemnet__closesocket(fd); + return; } + x->x_nconnections++; + i = x->x_nconnections - 1; + x->x_sr[i] = y; + + udpserver_info_connection(x, y); + } outlet_float(x->x_connectout, x->x_nconnections); } @@ -625,6 +686,8 @@ static void udpserver_port(t_udpserver*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; @@ -633,14 +696,17 @@ static void udpserver_port(t_udpserver*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_DGRAM, 0); - + if(sockfd<0) { + sys_sockerror("[udpserver]: cannot create UDP socket"); + return; + } server.sin_family = AF_INET; @@ -650,17 +716,17 @@ static void udpserver_port(t_udpserver*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("udpserver: bind"); - sys_closesocket(sockfd); - outlet_anything(x->x_statout, gensym("port"), 1, ap); - return; - } + if (bind(sockfd, (struct sockaddr *)&server, serversize) < 0) { + sys_sockerror("udpserver: bind"); + iemnet__closesocket(sockfd); + outlet_anything(x->x_statout, gensym("port"), 1, ap); + return; + } x->x_receiver=iemnet__receiver_create(sockfd, - x, - udpserver_receive_callback); + x, + udpserver_receive_callback, + 0); x->x_connectsocket = sockfd; x->x_port = portno; @@ -684,19 +750,20 @@ static void *udpserver_new(t_floatarg fportno) x = (t_udpserver *)pd_new(udpserver_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_connectsocket = -1; 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); @@ -712,45 +779,59 @@ static void udpserver_free(t_udpserver *x) { int i; - for(i = 0; i < MAX_CONNECT; i++) - { - if (NULL!=x->x_sr[i]) { - DEBUG("[%s] free %x", objName, x); - udpserver_sender_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); + for(i = 0; i < MAX_CONNECT; i++) { + if (NULL!=x->x_sr[i]) { + DEBUG("[%s] free %x", objName, x); + udpserver_sender_free(x->x_sr[i]); + x->x_sr[i]=NULL; } - 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 udpserver_setup(void) { - if(!iemnet__register(objName))return; + if(!iemnet__register(objName)) { + return; + } error("[%s] does not work yet", objName); - udpserver_class = class_new(gensym(objName),(t_newmethod)udpserver_new, (t_method)udpserver_free, + udpserver_class = class_new(gensym(objName),(t_newmethod)udpserver_new, + (t_method)udpserver_free, sizeof(t_udpserver), 0, A_DEFFLOAT, 0); - class_addmethod(udpserver_class, (t_method)udpserver_disconnect_client, gensym("disconnectclient"), A_DEFFLOAT, 0); - class_addmethod(udpserver_class, (t_method)udpserver_disconnect_socket, gensym("disconnectsocket"), A_DEFFLOAT, 0); - class_addmethod(udpserver_class, (t_method)udpserver_disconnect_all, gensym("disconnect"), 0); - - class_addmethod(udpserver_class, (t_method)udpserver_accept, gensym("accept"), A_FLOAT, 0); - - class_addmethod(udpserver_class, (t_method)udpserver_send_socket, gensym("send"), A_GIMME, 0); - class_addmethod(udpserver_class, (t_method)udpserver_send_client, gensym("client"), A_GIMME, 0); - - class_addmethod(udpserver_class, (t_method)udpserver_broadcast, gensym("broadcast"), A_GIMME, 0); - - class_addmethod(udpserver_class, (t_method)udpserver_defaulttarget, gensym("target"), A_DEFFLOAT, 0); - class_addmethod(udpserver_class, (t_method)udpserver_targetsocket, gensym("targetsocket"), A_DEFFLOAT, 0); + class_addmethod(udpserver_class, (t_method)udpserver_disconnect_client, + gensym("disconnectclient"), A_DEFFLOAT, 0); + class_addmethod(udpserver_class, (t_method)udpserver_disconnect_socket, + gensym("disconnectsocket"), A_DEFFLOAT, 0); + class_addmethod(udpserver_class, (t_method)udpserver_disconnect_all, + gensym("disconnect"), 0); + + class_addmethod(udpserver_class, (t_method)udpserver_accept, + gensym("accept"), A_FLOAT, 0); + + class_addmethod(udpserver_class, (t_method)udpserver_send_socket, + gensym("send"), A_GIMME, 0); + class_addmethod(udpserver_class, (t_method)udpserver_send_client, + gensym("client"), A_GIMME, 0); + + class_addmethod(udpserver_class, (t_method)udpserver_broadcast, + gensym("broadcast"), A_GIMME, 0); + + class_addmethod(udpserver_class, (t_method)udpserver_defaulttarget, + gensym("target"), A_DEFFLOAT, 0); + class_addmethod(udpserver_class, (t_method)udpserver_targetsocket, + gensym("targetsocket"), A_DEFFLOAT, 0); class_addlist (udpserver_class, (t_method)udpserver_defaultsend); - class_addmethod(udpserver_class, (t_method)udpserver_port, gensym("port"), A_DEFFLOAT, 0); + class_addmethod(udpserver_class, (t_method)udpserver_port, gensym("port"), + A_DEFFLOAT, 0); class_addbang (udpserver_class, (t_method)udpserver_info); DEBUGMETHOD(udpserver_class); -- cgit v1.2.1