summaryrefslogtreecommitdiff
path: root/apps/plugins/pdbox/PDa/src/x_net.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/pdbox/PDa/src/x_net.c')
-rw-r--r--apps/plugins/pdbox/PDa/src/x_net.c362
1 files changed, 0 insertions, 362 deletions
diff --git a/apps/plugins/pdbox/PDa/src/x_net.c b/apps/plugins/pdbox/PDa/src/x_net.c
index 5094661214..c4a004cc5c 100644
--- a/apps/plugins/pdbox/PDa/src/x_net.c
+++ b/apps/plugins/pdbox/PDa/src/x_net.c
@@ -361,366 +361,4 @@ void x_net_setup(void)
361 netreceive_setup(); 361 netreceive_setup();
362} 362}
363 363
364/* Copyright (c) 1997-1999 Miller Puckette.
365* For information on usage and redistribution, and for a DISCLAIMER OF ALL
366* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
367
368/* network */
369
370#include "m_pd.h"
371#include "s_stuff.h"
372
373#include <sys/types.h>
374#include <string.h>
375#ifdef UNIX
376#include <sys/socket.h>
377#include <netinet/in.h>
378#include <netinet/tcp.h>
379#include <netdb.h>
380#include <stdio.h>
381#define SOCKET_ERROR -1
382#else
383#include <winsock.h>
384#endif
385
386static t_class *netsend_class;
387
388typedef struct _netsend
389{
390 t_object x_obj;
391 int x_fd;
392 int x_protocol;
393} t_netsend;
394
395static void *netsend_new(t_floatarg udpflag)
396{
397 t_netsend *x = (t_netsend *)pd_new(netsend_class);
398 outlet_new(&x->x_obj, &s_float);
399 x->x_fd = -1;
400 x->x_protocol = (udpflag != 0 ? SOCK_DGRAM : SOCK_STREAM);
401 return (x);
402}
403
404static void netsend_connect(t_netsend *x, t_symbol *hostname,
405 t_floatarg fportno)
406{
407 struct sockaddr_in server;
408 struct hostent *hp;
409 int sockfd;
410 int portno = fportno;
411 int intarg;
412 if (x->x_fd >= 0)
413 {
414 error("netsend_connect: already connected");
415 return;
416 }
417
418 /* create a socket */
419 sockfd = socket(AF_INET, x->x_protocol, 0);
420#if 0
421 fprintf(stderr, "send socket %d\n", sockfd);
422#endif
423 if (sockfd < 0)
424 {
425 sys_sockerror("socket");
426 return;
427 }
428 /* connect socket using hostname provided in command line */
429 server.sin_family = AF_INET;
430 hp = gethostbyname(hostname->s_name);
431 if (hp == 0)
432 {
433 post("bad host?\n");
434 return;
435 }
436#if 0
437 intarg = 0;
438 if (setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF,
439 &intarg, sizeof(intarg)) < 0)
440 post("setsockopt (SO_RCVBUF) failed\n");
441#endif
442 /* for stream (TCP) sockets, specify "nodelay" */
443 if (x->x_protocol == SOCK_STREAM)
444 {
445 intarg = 1;
446 if (setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY,
447 &intarg, sizeof(intarg)) < 0)
448 post("setsockopt (TCP_NODELAY) failed\n");
449 }
450 memcpy((char *)&server.sin_addr, (char *)hp->h_addr, hp->h_length);
451
452 /* assign client port number */
453 server.sin_port = htons((u_short)portno);
454
455 post("connecting to port %d", portno);
456 /* try to connect. LATER make a separate thread to do this
457 because it might block */
458 if (connect(sockfd, (struct sockaddr *) &server, sizeof (server)) < 0)
459 {
460 sys_sockerror("connecting stream socket");
461 sys_closesocket(sockfd);
462 return;
463 }
464 x->x_fd = sockfd;
465 outlet_float(x->x_obj.ob_outlet, 1);
466}
467
468static void netsend_disconnect(t_netsend *x)
469{
470 if (x->x_fd >= 0)
471 {
472 sys_closesocket(x->x_fd);
473 x->x_fd = -1;
474 outlet_float(x->x_obj.ob_outlet, 0);
475 }
476}
477
478static void netsend_send(t_netsend *x, t_symbol *s, int argc, t_atom *argv)
479{
480 if (x->x_fd >= 0)
481 {
482 t_binbuf *b = binbuf_new();
483 char *buf, *bp;
484 int length, sent;
485 t_atom at;
486 binbuf_add(b, argc, argv);
487 SETSEMI(&at);
488 binbuf_add(b, 1, &at);
489 binbuf_gettext(b, &buf, &length);
490 for (bp = buf, sent = 0; sent < length;)
491 {
492 static double lastwarntime;
493 static double pleasewarn;
494 double timebefore = sys_getrealtime();
495 int res = send(x->x_fd, buf, length-sent, 0);
496 double timeafter = sys_getrealtime();
497 int late = (timeafter - timebefore > 0.005);
498 if (late || pleasewarn)
499 {
500 if (timeafter > lastwarntime + 2)
501 {
502 post("netsend blocked %d msec",
503 (int)(1000 * ((timeafter - timebefore) + pleasewarn)));
504 pleasewarn = 0;
505 lastwarntime = timeafter;
506 }
507 else if (late) pleasewarn += timeafter - timebefore;
508 }
509 if (res <= 0)
510 {
511 sys_sockerror("netsend");
512 netsend_disconnect(x);
513 break;
514 }
515 else
516 {
517 sent += res;
518 bp += res;
519 }
520 }
521 t_freebytes(buf, length);
522 binbuf_free(b);
523 }
524 else error("netsend: not connected");
525}
526
527static void netsend_free(t_netsend *x)
528{
529 netsend_disconnect(x);
530}
531
532static void netsend_setup(void)
533{
534 netsend_class = class_new(gensym("netsend"), (t_newmethod)netsend_new,
535 (t_method)netsend_free,
536 sizeof(t_netsend), 0, A_DEFFLOAT, 0);
537 class_addmethod(netsend_class, (t_method)netsend_connect,
538 gensym("connect"), A_SYMBOL, A_FLOAT, 0);
539 class_addmethod(netsend_class, (t_method)netsend_disconnect,
540 gensym("disconnect"), 0);
541 class_addmethod(netsend_class, (t_method)netsend_send, gensym("send"),
542 A_GIMME, 0);
543}
544
545/* ----------------------------- netreceive ------------------------- */
546
547static t_class *netreceive_class;
548
549typedef struct _netreceive
550{
551 t_object x_obj;
552 t_outlet *x_msgout;
553 t_outlet *x_connectout;
554 int x_connectsocket;
555 int x_nconnections;
556 int x_udp;
557} t_netreceive;
558
559static void netreceive_notify(t_netreceive *x)
560{
561 outlet_float(x->x_connectout, --x->x_nconnections);
562}
563
564static void netreceive_doit(void *z, t_binbuf *b)
565{
566 t_atom messbuf[1024];
567 t_netreceive *x = (t_netreceive *)z;
568 int msg, natom = binbuf_getnatom(b);
569 t_atom *at = binbuf_getvec(b);
570 for (msg = 0; msg < natom;)
571 {
572 int emsg;
573 for (emsg = msg; emsg < natom && at[emsg].a_type != A_COMMA
574 && at[emsg].a_type != A_SEMI; emsg++)
575 ;
576 if (emsg > msg)
577 {
578 int i;
579 for (i = msg; i < emsg; i++)
580 if (at[i].a_type == A_DOLLAR || at[i].a_type == A_DOLLSYM)
581 {
582 pd_error(x, "netreceive: got dollar sign in message");
583 goto nodice;
584 }
585 if (at[msg].a_type == A_FLOAT)
586 {
587 if (emsg > msg + 1)
588 outlet_list(x->x_msgout, 0, emsg-msg, at + msg);
589 else outlet_float(x->x_msgout, at[msg].a_w.w_float);
590 }
591 else if (at[msg].a_type == A_SYMBOL)
592 outlet_anything(x->x_msgout, at[msg].a_w.w_symbol,
593 emsg-msg-1, at + msg + 1);
594 }
595 nodice:
596 msg = emsg + 1;
597 }
598}
599
600static void netreceive_connectpoll(t_netreceive *x)
601{
602 int fd = accept(x->x_connectsocket, 0, 0);
603 if (fd < 0) post("netreceive: accept failed");
604 else
605 {
606 t_socketreceiver *y = socketreceiver_new((void *)x,
607 (t_socketnotifier)netreceive_notify,
608 (x->x_msgout ? netreceive_doit : 0), 0);
609 sys_addpollfn(fd, (t_fdpollfn)socketreceiver_read, y);
610 outlet_float(x->x_connectout, ++x->x_nconnections);
611 }
612}
613
614static void *netreceive_new(t_symbol *compatflag,
615 t_floatarg fportno, t_floatarg udpflag)
616{
617 t_netreceive *x;
618 struct sockaddr_in server;
619 int sockfd, portno = fportno, udp = (udpflag != 0);
620 int old = !strcmp(compatflag->s_name , "old");
621 int intarg;
622 /* create a socket */
623 sockfd = socket(AF_INET, (udp ? SOCK_DGRAM : SOCK_STREAM), 0);
624#if 0
625 fprintf(stderr, "receive socket %d\n", sockfd);
626#endif
627 if (sockfd < 0)
628 {
629 sys_sockerror("socket");
630 return (0);
631 }
632 server.sin_family = AF_INET;
633 server.sin_addr.s_addr = INADDR_ANY;
634
635#if 1
636 /* ask OS to allow another Pd to repoen this port after we close it. */
637 intarg = 1;
638 if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR,
639 &intarg, sizeof(intarg)) < 0)
640 post("setsockopt (SO_REUSEADDR) failed\n");
641#endif
642#if 0
643 intarg = 0;
644 if (setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF,
645 &intarg, sizeof(intarg)) < 0)
646 post("setsockopt (SO_RCVBUF) failed\n");
647#endif
648 /* Stream (TCP) sockets are set NODELAY */
649 if (!udp)
650 {
651 intarg = 1;
652 if (setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY,
653 &intarg, sizeof(intarg)) < 0)
654 post("setsockopt (TCP_NODELAY) failed\n");
655 }
656 /* assign server port number */
657 server.sin_port = htons((u_short)portno);
658
659 /* name the socket */
660 if (bind(sockfd, (struct sockaddr *)&server, sizeof(server)) < 0)
661 {
662 sys_sockerror("bind");
663 sys_closesocket(sockfd);
664 return (0);
665 }
666 x = (t_netreceive *)pd_new(netreceive_class);
667 if (old)
668 {
669 /* old style, nonsecure version */
670 x->x_msgout = 0;
671 }
672 else x->x_msgout = outlet_new(&x->x_obj, &s_anything);
673
674 if (udp) /* datagram protocol */
675 {
676 t_socketreceiver *y = socketreceiver_new((void *)x,
677 (t_socketnotifier)netreceive_notify,
678 (x->x_msgout ? netreceive_doit : 0), 1);
679 sys_addpollfn(sockfd, (t_fdpollfn)socketreceiver_read, y);
680 x->x_connectout = 0;
681 }
682 else /* streaming protocol */
683 {
684 if (listen(sockfd, 5) < 0)
685 {
686 sys_sockerror("listen");
687 sys_closesocket(sockfd);
688 sockfd = -1;
689 }
690 else
691 {
692 sys_addpollfn(sockfd, (t_fdpollfn)netreceive_connectpoll, x);
693 x->x_connectout = outlet_new(&x->x_obj, &s_float);
694 }
695 }
696 x->x_connectsocket = sockfd;
697 x->x_nconnections = 0;
698 x->x_udp = udp;
699
700 return (x);
701}
702
703static void netreceive_free(t_netreceive *x)
704{
705 /* LATER make me clean up open connections */
706 if (x->x_connectsocket >= 0)
707 {
708 sys_rmpollfn(x->x_connectsocket);
709 sys_closesocket(x->x_connectsocket);
710 }
711}
712
713static void netreceive_setup(void)
714{
715 netreceive_class = class_new(gensym("netreceive"),
716 (t_newmethod)netreceive_new, (t_method)netreceive_free,
717 sizeof(t_netreceive), CLASS_NOINLET, A_DEFFLOAT, A_DEFFLOAT,
718 A_DEFSYM, 0);
719}
720
721void x_net_setup(void)
722{
723 netsend_setup();
724 netreceive_setup();
725}
726 364