static void udpreceive_port(t_udpreceive*x, t_floatarg fportno) { static t_atom ap[1]; int portno = fportno; struct sockaddr_in server; socklen_t serversize=sizeof(server); int sockfd = x->x_connectsocket; int intarg; SETFLOAT(ap, -1); if(x->x_port == portno) { return; } /* cleanup any open ports */ if(sockfd>=0) { iemnet__receiver_destroy(x->x_receiver); x->x_connectsocket=-1; x->x_port=-1; } sockfd = socket(AF_INET, SOCK_DGRAM, 0); if(sockfd<0) { error("[%s]: unable to create socket", objName); return; } /* ask OS to allow another Pd to reopen this port after we close it. */ #ifdef SO_REUSEADDR intarg = 1; if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char *)&intarg, sizeof(intarg)) < 0) { error("[%s]: setsockopt (SO_REUSEADDR) failed", objName); } #endif /* SO_REUSEADDR */ #ifdef SO_REUSEPORT intarg = 1; if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEPORT, (char *)&intarg, sizeof(intarg)) < 0) { error("[%s]: setsockopt (SO_REUSEPORT) failed", objName); } #endif /* SO_REUSEPORT */ server.sin_family = AF_INET; server.sin_addr.s_addr = INADDR_ANY; server.sin_port = htons((u_short)portno); /* name the socket */ if (bind(sockfd, (struct sockaddr *)&server, serversize) < 0) { sys_sockerror("[udpreceive] bind failed"); sys_closesocket(sockfd); sockfd = -1; outlet_anything(x->x_statout, gensym("port"), 1, ap); return; } x->x_connectsocket = sockfd; x->x_port = portno; // find out which port is actually used (useful when assigning "0") if(!getsockname(sockfd, (struct sockaddr *)&server, &serversize)) { x->x_port=ntohs(server.sin_port); } x->x_receiver=iemnet__receiver_create(sockfd, x, udpreceive_read_callback); SETFLOAT(ap, x->x_port); outlet_anything(x->x_statout, gensym("port"), 1, ap); }
static int udpreceive_setport(t_udpreceive*x, unsigned short portno) { struct sockaddr_in server; socklen_t serversize=sizeof(server); int sockfd = x->x_connectsocket; int intarg; memset(&server, 0, sizeof(server)); if(x->x_port == portno) { return 1; } /* cleanup any open ports */ if(sockfd>=0) { iemnet__receiver_destroy(x->x_receiver, 0); x->x_connectsocket=-1; x->x_port=-1; } sockfd = socket(AF_INET, SOCK_DGRAM, 0); if(sockfd<0) { pd_error(x, "[%s]: unable to create socket", objName); return 0; } /* ask OS to allow another Pd to reopen this port after we close it. */ #ifdef SO_REUSEADDR if(x->x_reuseaddr) { intarg = 1; if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (void *)&intarg, sizeof(intarg)) < 0) { pd_error(x, "[%s]: setsockopt (SO_REUSEADDR) failed", objName); } } #endif /* SO_REUSEADDR */ #ifdef SO_REUSEPORT if(x->x_reuseport) { intarg = 1; if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEPORT, (void *)&intarg, sizeof(intarg)) < 0) { pd_error(x, "[%s]: setsockopt (SO_REUSEPORT) failed", objName); } } #endif /* SO_REUSEPORT */ server.sin_family = AF_INET; server.sin_addr.s_addr = INADDR_ANY; server.sin_port = htons((u_short)portno); /* name the socket */ if (bind(sockfd, (struct sockaddr *)&server, serversize) < 0) { sys_sockerror("[udpreceive] bind failed"); sys_closesocket(sockfd); sockfd = -1; return 0; } x->x_connectsocket = sockfd; x->x_port = portno; // find out which port is actually used (useful when assigning "0") if(!getsockname(sockfd, (struct sockaddr *)&server, &serversize)) { x->x_port=ntohs(server.sin_port); } x->x_receiver=iemnet__receiver_create(sockfd, x, udpreceive_read_callback, 0); return 1; }
static void *udpclient_child_connect(void *w) { t_udpclient *x = (t_udpclient*) w; struct sockaddr_in server; struct hostent *hp; int sockfd; int broadcast = 1;/* nonzero is true */ if (x->x_sender) { error("[%s] already connected", objName); return (x); } /* create a socket */ sockfd = socket(AF_INET, SOCK_DGRAM, 0); DEBUG("send socket %d\n", sockfd); if (sockfd < 0) { sys_sockerror("udpclient: socket"); return (x); } /* Based on zmoelnig's patch 2221504: Enable sending of broadcast messages (if hostname is a broadcast address)*/ #ifdef SO_BROADCAST if( 0 != setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, (const void *)&broadcast, sizeof(broadcast))) { error("[%s] couldn't switch to broadcast mode", objName); } #endif /* SO_BROADCAST */ /* connect socket using hostname provided in command line */ server.sin_family = AF_INET; hp = gethostbyname(x->x_hostname); if (hp == 0) { error("[%s] bad host '%s'?", objName, x->x_hostname); return (x); } memcpy((char *)&server.sin_addr, (char *)hp->h_addr, hp->h_length); /* assign client port number */ server.sin_port = htons((u_short)x->x_port); DEBUG("connecting to port %d", x->x_port); /* try to connect. */ if (connect(sockfd, (struct sockaddr *) &server, sizeof (server)) < 0) { sys_sockerror("udpclient: connecting stream socket"); sys_closesocket(sockfd); return (x); } x->x_fd = sockfd; x->x_addr = ntohl(*(long *)hp->h_addr); x->x_sender=iemnet__sender_create(sockfd); x->x_receiver=iemnet__receiver_create(sockfd, x, udpclient_receive_callback); x->x_connectstate = 1; clock_delay(x->x_clock, 0); return (x); }
static void *tcpclient_child_connect(void *w) { t_tcpclient *x = (t_tcpclient*) w; struct sockaddr_in server; struct hostent *hp; int sockfd; t_iemnet_sender*sender; t_iemnet_receiver*receiver; if (x->x_fd >= 0) { error("%s_connect: already connected", objName); return (x); } /* create a socket */ sockfd = socket(AF_INET, SOCK_STREAM, 0); DEBUG("send socket %d\n", sockfd); if (sockfd < 0) { sys_sockerror("tcpclient: socket"); return (x); } /* connect socket using hostname provided in command line */ server.sin_family = AF_INET; hp = gethostbyname(x->x_hostname); if (hp == 0) { sys_sockerror("tcpclient: 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)x->x_port); /* try to connect */ if (connect(sockfd, (struct sockaddr *) &server, sizeof (server)) < 0) { sys_sockerror("tcpclient: connecting stream socket"); sys_closesocket(sockfd); return (x); } sender=iemnet__sender_create(sockfd); receiver=iemnet__receiver_create(sockfd, x, tcpclient_receive_callback); /* update the tcpclient-object (thread safe) */ sys_lock(); x->x_fd = sockfd; x->x_addr = ntohl(*(long *)hp->h_addr); x->x_sender=sender; x->x_receiver=receiver; x->x_connectstate = 1; /* use callback to set outlet in main thread */ clock_delay(x->x_clock, 0); sys_unlock(); return (x); }