From 71b83fc040b848c98c5065d95ecbc72b0b4f8943 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 17 Jan 2013 22:54:00 +0000 Subject: merging maxlib v1.5.5 from branches/pd-extended/0.43 svn path=/trunk/externals/maxlib/; revision=16897 --- netclient.c | 764 ++++++++++++++++++++++++++++++------------------------------ 1 file changed, 382 insertions(+), 382 deletions(-) (limited to 'netclient.c') diff --git a/netclient.c b/netclient.c index 3a024cd..7436aed 100644 --- a/netclient.c +++ b/netclient.c @@ -1,396 +1,396 @@ -/* -------------------------- netclient ------------------------------------- */ -/* */ -/* Extended 'netsend', connects to 'netserver'. */ -/* Uses child thread to connect to server. Thus needs pd0.35-test17 or later. */ -/* Written by Olaf Matthes (olaf.matthes@gmx.de) */ +/* -------------------------- netclient ------------------------------------- */ +/* */ +/* Extended 'netsend', connects to 'netserver'. */ +/* Uses child thread to connect to server. Thus needs pd0.35-test17 or later. */ +/* Written by Olaf Matthes (olaf.matthes@gmx.de) */ /* Get source at */ /* http://pure-data.svn.sourceforge.net/viewvc/pure-data/trunk/externals/maxlib/src/netclient.c */ /* March 26 2010 */ /* Additional fixes and improvements by Ivica Ico Bukvic */ /* for the purpose of L2Ork http://l2ork.music.vt.edu */ -/* This program is free software; you can redistribute it and/or */ -/* modify it under the terms of the GNU General Public License */ -/* as published by the Free Software Foundation; either version 2 */ -/* of the License, or (at your option) any later version. */ -/* */ -/* This program is distributed in the hope that it will be useful, */ -/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ -/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ -/* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* */ -/* Based on PureData by Miller Puckette and others. */ -/* */ -/* ---------------------------------------------------------------------------- */ -/* Changes: use circular message buffer for receive */ -/* using pollfunction instead of clock (suggested by HCS) */ - -#include "m_pd.h" -#include "s_stuff.h" -#include "m_imp.h" - -#include -#include -#include -#ifdef WIN32 -#include -#else -#include -#include -#include -#include -#include -#include -#include -#define SOCKET_ERROR -1 -#endif - -#define INBUFSIZE 4096 /* maximum numbers of characters to read */ - -static char *version = "netclient v0.3.1, written by Olaf Matthes "; - -static t_class *netclient_class; -static t_binbuf *inbinbuf; -static int netclient_instance_count; - -typedef struct _netclient -{ - t_object x_obj; - t_clock *x_clock; - t_outlet *x_outdata; - t_outlet *x_outconnect; - int x_fd; - char *x_hostname; - int x_connectstate; - int x_port; - int x_protocol; - char x_inbuf[INBUFSIZE]; /* circular message buffer for received data */ - int x_intail; - int x_inhead; - /* multithread stuff */ - pthread_t x_threadid; /* id of child thread */ - pthread_attr_t x_threadattr; /* attributes of child thread */ -} t_netclient; - - /* one lonely prototype */ -static void netclient_rcv(t_netclient *x); - - - /* gets called when connection status has changed */ -static void netclient_tick(t_netclient *x) -{ +/* This program is free software; you can redistribute it and/or */ +/* modify it under the terms of the GNU General Public License */ +/* as published by the Free Software Foundation; either version 2 */ +/* of the License, or (at your option) any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, */ +/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ +/* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* */ +/* Based on PureData by Miller Puckette and others. */ +/* */ +/* ---------------------------------------------------------------------------- */ +/* Changes: use circular message buffer for receive */ +/* using pollfunction instead of clock (suggested by HCS) */ + +#include "m_pd.h" +#include "s_stuff.h" +#include "m_imp.h" + +#include +#include +#include +#ifdef WIN32 +#include +#else +#include +#include +#include +#include +#include +#include +#include +#define SOCKET_ERROR -1 +#endif + +#define INBUFSIZE 4096 /* maximum numbers of characters to read */ + +static char *version = "netclient v0.3.1, written by Olaf Matthes "; + +static t_class *netclient_class; +static t_binbuf *inbinbuf; +static int netclient_instance_count; + +typedef struct _netclient +{ + t_object x_obj; + t_clock *x_clock; + t_outlet *x_outdata; + t_outlet *x_outconnect; + int x_fd; + char *x_hostname; + int x_connectstate; + int x_port; + int x_protocol; + char x_inbuf[INBUFSIZE]; /* circular message buffer for received data */ + int x_intail; + int x_inhead; + /* multithread stuff */ + pthread_t x_threadid; /* id of child thread */ + pthread_attr_t x_threadattr; /* attributes of child thread */ +} t_netclient; + + /* one lonely prototype */ +static void netclient_rcv(t_netclient *x); + + + /* gets called when connection status has changed */ +static void netclient_tick(t_netclient *x) +{ outlet_float(x->x_outconnect, x->x_connectstate); /* add pollfunction for checking for input */ if (x->x_connectstate == 1) { sys_addpollfn(x->x_fd, (t_fdpollfn)netclient_rcv, x); } -} - -static void *netclient_child_connect(void *w) -{ - t_netclient *x = (t_netclient*) w; - struct sockaddr_in server; - struct hostent *hp; - int sockfd; - int portno = x->x_port; - if (x->x_fd >= 0) - { - error("netclient_connect: already connected"); - return (x); - } - - /* create a socket */ - sockfd = socket(AF_INET, x->x_protocol, 0); -#if 0 - fprintf(stderr, "send socket %d\n", sockfd); -#endif - if (sockfd < 0) - { - sys_sockerror("socket"); - return (x); - } - /* connect socket using hostname provided in command line */ - server.sin_family = AF_INET; - hp = gethostbyname(x->x_hostname); - if (hp == 0) - { - post("bad host?\n"); - return (x); - } - memcpy((char *)&server.sin_addr, (char *)hp->h_addr, hp->h_length); - - /* assign client port number */ - server.sin_port = htons((u_short)portno); - - post("connecting to port %d", portno); - /* try to connect */ - if (connect(sockfd, (struct sockaddr *) &server, sizeof (server)) < 0) - { - sys_sockerror("connecting stream socket"); - sys_closesocket(sockfd); - return (x); - } - x->x_fd = sockfd; - /* outlet_float is not threadsafe ! */ - // outlet_float(x->x_obj.ob_outlet, 1); - x->x_connectstate = 1; - /* use callback instead to set outlet */ - clock_delay(x->x_clock, 0); - return (x); -} - -static void netclient_connect(t_netclient *x, t_symbol *hostname, - t_floatarg fportno) -{ - /* we get hostname and port and pass them on - to the child thread that establishes the connection */ - x->x_hostname = hostname->s_name; - x->x_port = fportno; - x->x_connectstate = 0; - /* start child thread */ - if(pthread_create( &x->x_threadid, &x->x_threadattr, netclient_child_connect, x) < 0) - post("netclient: could not create new thread"); -} - -static void netclient_disconnect(t_netclient *x) -{ - if (x->x_fd >= 0) - { - sys_rmpollfn(x->x_fd); - sys_closesocket(x->x_fd); - x->x_fd = -1; - x->x_connectstate = 0; - //outlet_float(x->x_outconnect, 0); +} + +static void *netclient_child_connect(void *w) +{ + t_netclient *x = (t_netclient*) w; + struct sockaddr_in server; + struct hostent *hp; + int sockfd; + int portno = x->x_port; + if (x->x_fd >= 0) + { + error("netclient_connect: already connected"); + return (x); + } + + /* create a socket */ + sockfd = socket(AF_INET, x->x_protocol, 0); +#if 0 + fprintf(stderr, "send socket %d\n", sockfd); +#endif + if (sockfd < 0) + { + sys_sockerror("socket"); + return (x); + } + /* connect socket using hostname provided in command line */ + server.sin_family = AF_INET; + hp = gethostbyname(x->x_hostname); + if (hp == 0) + { + post("bad host?\n"); + return (x); + } + memcpy((char *)&server.sin_addr, (char *)hp->h_addr, hp->h_length); + + /* assign client port number */ + server.sin_port = htons((u_short)portno); + + post("connecting to port %d", portno); + /* try to connect */ + if (connect(sockfd, (struct sockaddr *) &server, sizeof (server)) < 0) + { + sys_sockerror("connecting stream socket"); + sys_closesocket(sockfd); + return (x); + } + x->x_fd = sockfd; + /* outlet_float is not threadsafe ! */ + // outlet_float(x->x_obj.ob_outlet, 1); + x->x_connectstate = 1; + /* use callback instead to set outlet */ + clock_delay(x->x_clock, 0); + return (x); +} + +static void netclient_connect(t_netclient *x, t_symbol *hostname, + t_floatarg fportno) +{ + /* we get hostname and port and pass them on + to the child thread that establishes the connection */ + x->x_hostname = hostname->s_name; + x->x_port = fportno; + x->x_connectstate = 0; + /* start child thread */ + if(pthread_create( &x->x_threadid, &x->x_threadattr, netclient_child_connect, x) < 0) + post("netclient: could not create new thread"); +} + +static void netclient_disconnect(t_netclient *x) +{ + if (x->x_fd >= 0) + { + sys_rmpollfn(x->x_fd); + sys_closesocket(x->x_fd); + x->x_fd = -1; + x->x_connectstate = 0; + //outlet_float(x->x_outconnect, 0); clock_delay(x->x_clock, 0); /* output connect state later */ - } -} - -static void netclient_send(t_netclient *x, t_symbol *s, int argc, t_atom *argv) -{ - if (x->x_fd >= 0) - { - t_binbuf *b = binbuf_new(); - char *buf, *bp; - int length, sent; - t_atom at; - binbuf_add(b, argc, argv); - SETSEMI(&at); - binbuf_add(b, 1, &at); - binbuf_gettext(b, &buf, &length); - for (bp = buf, sent = 0; sent < length;) - { - static double lastwarntime; - static double pleasewarn; - double timebefore = sys_getrealtime(); - int res = send(x->x_fd, buf, length-sent, 0); - double timeafter = sys_getrealtime(); - int late = (timeafter - timebefore > 0.005); - if (late || pleasewarn) - { - if (timeafter > lastwarntime + 2) - { - post("netclient blocked %d msec", - (int)(1000 * ((timeafter - timebefore) + pleasewarn))); - pleasewarn = 0; - lastwarntime = timeafter; - } - else if (late) pleasewarn += timeafter - timebefore; - } - if (res <= 0) - { - sys_sockerror("netclient"); - netclient_disconnect(x); - break; - } - else - { - sent += res; - bp += res; - } - } - t_freebytes(buf, length); - binbuf_free(b); - } - else error("netclient: not connected"); -} - - /* this is in a separately called subroutine so that the buffer isn't - sitting on the stack while the messages are getting passed. */ -static int netclient_doread(t_netclient *x) -{ - char messbuf[INBUFSIZE], *bp = messbuf; - int indx; - int inhead = x->x_inhead; - int intail = x->x_intail; - char *inbuf = x->x_inbuf; - if (intail == inhead) return (0); - for (indx = intail; indx != inhead; indx = (indx+1)&(INBUFSIZE-1)) - { - char c = *bp++ = inbuf[indx]; - if (c == ';' && (!indx || inbuf[indx-1] != '\\')) - { - intail = (indx+1)&(INBUFSIZE-1); - binbuf_text(inbinbuf, messbuf, bp - messbuf); - x->x_inhead = inhead; - x->x_intail = intail; - return (1); - } - } - return (0); -} - -static void netclient_rcv(t_netclient *x) -{ - int fd = x->x_fd; - int ret; - fd_set readset; - fd_set exceptset; - struct timeval ztout; - /* output data */ - int msg, natom; - t_atom *at; - - if(x->x_connectstate) - { - /* check if we can read/write from/to the socket */ - FD_ZERO(&readset); - FD_ZERO(&exceptset); - FD_SET(fd, &readset ); - FD_SET(fd, &exceptset ); - - ztout.tv_sec = 0; - ztout.tv_usec = 0; - ret = select(fd+1, &readset, NULL, &exceptset, &ztout); - if(ret < 0) - { - error("netclient: can not read from socket"); + } +} + +static void netclient_send(t_netclient *x, t_symbol *s, int argc, t_atom *argv) +{ + if (x->x_fd >= 0) + { + t_binbuf *b = binbuf_new(); + char *buf, *bp; + int length, sent; + t_atom at; + binbuf_add(b, argc, argv); + SETSEMI(&at); + binbuf_add(b, 1, &at); + binbuf_gettext(b, &buf, &length); + for (bp = buf, sent = 0; sent < length;) + { + static double lastwarntime; + static double pleasewarn; + double timebefore = sys_getrealtime(); + int res = send(x->x_fd, buf, length-sent, 0); + double timeafter = sys_getrealtime(); + int late = (timeafter - timebefore > 0.005); + if (late || pleasewarn) + { + if (timeafter > lastwarntime + 2) + { + post("netclient blocked %d msec", + (int)(1000 * ((timeafter - timebefore) + pleasewarn))); + pleasewarn = 0; + lastwarntime = timeafter; + } + else if (late) pleasewarn += timeafter - timebefore; + } + if (res <= 0) + { + sys_sockerror("netclient"); + netclient_disconnect(x); + break; + } + else + { + sent += res; + bp += res; + } + } + t_freebytes(buf, length); + binbuf_free(b); + } + else error("netclient: not connected"); +} + + /* this is in a separately called subroutine so that the buffer isn't + sitting on the stack while the messages are getting passed. */ +static int netclient_doread(t_netclient *x) +{ + char messbuf[INBUFSIZE], *bp = messbuf; + int indx; + int inhead = x->x_inhead; + int intail = x->x_intail; + char *inbuf = x->x_inbuf; + if (intail == inhead) return (0); + for (indx = intail; indx != inhead; indx = (indx+1)&(INBUFSIZE-1)) + { + char c = *bp++ = inbuf[indx]; + if (c == ';' && (!indx || inbuf[indx-1] != '\\')) + { + intail = (indx+1)&(INBUFSIZE-1); + binbuf_text(inbinbuf, messbuf, bp - messbuf); + x->x_inhead = inhead; + x->x_intail = intail; + return (1); + } + } + return (0); +} + +static void netclient_rcv(t_netclient *x) +{ + int fd = x->x_fd; + int ret; + fd_set readset; + fd_set exceptset; + struct timeval ztout; + /* output data */ + int msg, natom; + t_atom *at; + + if(x->x_connectstate) + { + /* check if we can read/write from/to the socket */ + FD_ZERO(&readset); + FD_ZERO(&exceptset); + FD_SET(fd, &readset ); + FD_SET(fd, &exceptset ); + + ztout.tv_sec = 0; + ztout.tv_usec = 0; + ret = select(fd+1, &readset, NULL, &exceptset, &ztout); + if(ret < 0) + { + error("netclient: can not read from socket"); //sys_closesocket(fd); - netclient_disconnect(x); - return; - } - if(FD_ISSET(fd, &readset) || FD_ISSET(fd, &exceptset)) - { - int readto = (x->x_inhead >= x->x_intail ? INBUFSIZE : x->x_intail-1); - - ret = recv(fd, x->x_inbuf + x->x_inhead, readto - x->x_inhead, 0); - if (ret < 0) - { - sys_sockerror("recv"); - //sys_rmpollfn(fd); + netclient_disconnect(x); + return; + } + if(FD_ISSET(fd, &readset) || FD_ISSET(fd, &exceptset)) + { + int readto = (x->x_inhead >= x->x_intail ? INBUFSIZE : x->x_intail-1); + + ret = recv(fd, x->x_inbuf + x->x_inhead, readto - x->x_inhead, 0); + if (ret < 0) + { + sys_sockerror("recv"); + //sys_rmpollfn(fd); //sys_closesocket(fd); - netclient_disconnect(x); - } - else if (ret == 0) - { - post("netclient: connection closed on socket %d", fd); - //sys_rmpollfn(fd); - //sys_closesocket(fd); - netclient_disconnect(x); - } - else - { - x->x_inhead += ret; - if (x->x_inhead >= INBUFSIZE) x->x_inhead = 0; - while (netclient_doread(x)) - { - /* output binbuf */ - natom = binbuf_getnatom(inbinbuf); /* get number of atoms */ - at = binbuf_getvec(inbinbuf); /* get the atoms */ - /* now split it into several parts at every A_SEMI because - we probably received more than one message at a time */ - for (msg = 0; msg < natom;) - { - int emsg; - for (emsg = msg; emsg < natom && at[emsg].a_type != A_COMMA - && at[emsg].a_type != A_SEMI; emsg++); - - if (emsg > msg) - { - int ii; - for (ii = msg; ii < emsg; ii++) - if (at[ii].a_type == A_DOLLAR || at[ii].a_type == A_DOLLSYM) - { - pd_error(x, "netserver: -- got dollar sign in message"); - goto nodice; - } - if (at[msg].a_type == A_FLOAT) - { - if (emsg > msg + 1) - outlet_list(x->x_outdata, 0, emsg-msg, at + msg); - else outlet_float(x->x_outdata, at[msg].a_w.w_float); - } - else if (at[msg].a_type == A_SYMBOL) - outlet_anything(x->x_outdata, at[msg].a_w.w_symbol, - emsg-msg-1, at + msg + 1); - } - nodice: - msg = emsg + 1; - } - } - } - } - } - else post("netclient: not connected"); -} - -static void *netclient_new(t_floatarg udpflag) -{ - t_netclient *x = (t_netclient *)pd_new(netclient_class); - x->x_outdata = outlet_new(&x->x_obj, &s_anything); /* received data */ - x->x_outconnect = outlet_new(&x->x_obj, &s_float); /* connection state */ - x->x_clock = clock_new(x, (t_method)netclient_tick); - if(netclient_instance_count == 0) - inbinbuf = binbuf_new(); - x->x_fd = -1; - x->x_protocol = (udpflag != 0 ? SOCK_DGRAM : SOCK_STREAM); - /* prepare child thread */ - if(pthread_attr_init(&x->x_threadattr) < 0) - post("netclient: warning: could not prepare child thread" ); - if(pthread_attr_setdetachstate(&x->x_threadattr, PTHREAD_CREATE_DETACHED) < 0) - post("netclient: warning: could not prepare child thread" ); - netclient_instance_count++; - return (x); -} - -static void netclient_free(t_netclient *x) -{ - netclient_disconnect(x); - clock_free(x->x_clock); - netclient_instance_count--; - if(netclient_instance_count == 0) - binbuf_free(inbinbuf); -} - -#ifndef MAXLIB -void netclient_setup(void) -{ - netclient_class = class_new(gensym("netclient"), (t_newmethod)netclient_new, - (t_method)netclient_free, - sizeof(t_netclient), 0, A_DEFFLOAT, 0); - class_addmethod(netclient_class, (t_method)netclient_connect, gensym("connect"), A_SYMBOL, A_FLOAT, 0); - class_addmethod(netclient_class, (t_method)netclient_disconnect, gensym("disconnect"), 0); - class_addmethod(netclient_class, (t_method)netclient_send, gensym("send"), A_GIMME, 0); - class_addmethod(netclient_class, (t_method)netclient_rcv, gensym("receive"), 0); - class_addmethod(netclient_class, (t_method)netclient_rcv, gensym("rcv"), 0); - - post(version); -} -#else -void maxlib_netclient_setup(void) -{ - netclient_class = class_new(gensym("maxlib_netclient"), (t_newmethod)netclient_new, - (t_method)netclient_free, - sizeof(t_netclient), 0, A_DEFFLOAT, 0); - class_addcreator((t_newmethod)netclient_new, gensym("netclient"), A_DEFFLOAT, 0); - class_addmethod(netclient_class, (t_method)netclient_connect, gensym("connect"), A_SYMBOL, A_FLOAT, 0); - class_addmethod(netclient_class, (t_method)netclient_disconnect, gensym("disconnect"), 0); - class_addmethod(netclient_class, (t_method)netclient_send, gensym("send"), A_GIMME, 0); - class_addmethod(netclient_class, (t_method)netclient_rcv, gensym("receive"), 0); - class_addmethod(netclient_class, (t_method)netclient_rcv, gensym("rcv"), 0); - class_sethelpsymbol(netclient_class, gensym("maxlib/netclient-help.pd")); -} -#endif + netclient_disconnect(x); + } + else if (ret == 0) + { + post("netclient: connection closed on socket %d", fd); + //sys_rmpollfn(fd); + //sys_closesocket(fd); + netclient_disconnect(x); + } + else + { + x->x_inhead += ret; + if (x->x_inhead >= INBUFSIZE) x->x_inhead = 0; + while (netclient_doread(x)) + { + /* output binbuf */ + natom = binbuf_getnatom(inbinbuf); /* get number of atoms */ + at = binbuf_getvec(inbinbuf); /* get the atoms */ + /* now split it into several parts at every A_SEMI because + we probably received more than one message at a time */ + for (msg = 0; msg < natom;) + { + int emsg; + for (emsg = msg; emsg < natom && at[emsg].a_type != A_COMMA + && at[emsg].a_type != A_SEMI; emsg++); + + if (emsg > msg) + { + int ii; + for (ii = msg; ii < emsg; ii++) + if (at[ii].a_type == A_DOLLAR || at[ii].a_type == A_DOLLSYM) + { + pd_error(x, "netserver: -- got dollar sign in message"); + goto nodice; + } + if (at[msg].a_type == A_FLOAT) + { + if (emsg > msg + 1) + outlet_list(x->x_outdata, 0, emsg-msg, at + msg); + else outlet_float(x->x_outdata, at[msg].a_w.w_float); + } + else if (at[msg].a_type == A_SYMBOL) + outlet_anything(x->x_outdata, at[msg].a_w.w_symbol, + emsg-msg-1, at + msg + 1); + } + nodice: + msg = emsg + 1; + } + } + } + } + } + else post("netclient: not connected"); +} + +static void *netclient_new(t_floatarg udpflag) +{ + t_netclient *x = (t_netclient *)pd_new(netclient_class); + x->x_outdata = outlet_new(&x->x_obj, &s_anything); /* received data */ + x->x_outconnect = outlet_new(&x->x_obj, &s_float); /* connection state */ + x->x_clock = clock_new(x, (t_method)netclient_tick); + if(netclient_instance_count == 0) + inbinbuf = binbuf_new(); + x->x_fd = -1; + x->x_protocol = (udpflag != 0 ? SOCK_DGRAM : SOCK_STREAM); + /* prepare child thread */ + if(pthread_attr_init(&x->x_threadattr) < 0) + post("netclient: warning: could not prepare child thread" ); + if(pthread_attr_setdetachstate(&x->x_threadattr, PTHREAD_CREATE_DETACHED) < 0) + post("netclient: warning: could not prepare child thread" ); + netclient_instance_count++; + return (x); +} + +static void netclient_free(t_netclient *x) +{ + netclient_disconnect(x); + clock_free(x->x_clock); + netclient_instance_count--; + if(netclient_instance_count == 0) + binbuf_free(inbinbuf); +} + +#ifndef MAXLIB +void netclient_setup(void) +{ + netclient_class = class_new(gensym("netclient"), (t_newmethod)netclient_new, + (t_method)netclient_free, + sizeof(t_netclient), 0, A_DEFFLOAT, 0); + class_addmethod(netclient_class, (t_method)netclient_connect, gensym("connect"), A_SYMBOL, A_FLOAT, 0); + class_addmethod(netclient_class, (t_method)netclient_disconnect, gensym("disconnect"), 0); + class_addmethod(netclient_class, (t_method)netclient_send, gensym("send"), A_GIMME, 0); + class_addmethod(netclient_class, (t_method)netclient_rcv, gensym("receive"), 0); + class_addmethod(netclient_class, (t_method)netclient_rcv, gensym("rcv"), 0); + + logpost(NULL, 4, version); +} +#else +void maxlib_netclient_setup(void) +{ + netclient_class = class_new(gensym("maxlib_netclient"), (t_newmethod)netclient_new, + (t_method)netclient_free, + sizeof(t_netclient), 0, A_DEFFLOAT, 0); + class_addcreator((t_newmethod)netclient_new, gensym("netclient"), A_DEFFLOAT, 0); + class_addmethod(netclient_class, (t_method)netclient_connect, gensym("connect"), A_SYMBOL, A_FLOAT, 0); + class_addmethod(netclient_class, (t_method)netclient_disconnect, gensym("disconnect"), 0); + class_addmethod(netclient_class, (t_method)netclient_send, gensym("send"), A_GIMME, 0); + class_addmethod(netclient_class, (t_method)netclient_rcv, gensym("receive"), 0); + class_addmethod(netclient_class, (t_method)netclient_rcv, gensym("rcv"), 0); + class_sethelpsymbol(netclient_class, gensym("maxlib/netclient-help.pd")); +} +#endif -- cgit v1.2.1