diff --git a/src/multicast.c b/src/multicast.c index 2b50055fb..639b2a409 100644 --- a/src/multicast.c +++ b/src/multicast.c @@ -317,6 +317,7 @@ int multicast_init(RIG *rig, char *addr, int port) rig->state.multicast->runflag = 1; pthread_create(&rig->state.multicast->threadid, NULL, multicast_thread, (void *)rig); + printf("threadid=%ld\n", rig->state.multicast->threadid); rig->state.multicast->multicast_running = 1; return RIG_OK; } @@ -390,7 +391,7 @@ int main(int argc, char *argv[]) strncpy(rig->state.rigport.pathname, "/dev/ttyUSB0", HAMLIB_FILPATHLEN - 1); rig->state.rigport.parm.serial.rate = 38400; rig_open(rig); - multicast_init(rig, NULL, 0); + multicast_init(rig, "224.0.0.1", 4532); pthread_join(rig->state.multicast->threadid, NULL); pthread_exit(NULL); return 0; diff --git a/tests/multicastclient.c b/tests/multicastclient.c index d5a6f5a30..c0c171ae5 100644 --- a/tests/multicastclient.c +++ b/tests/multicastclient.c @@ -1,88 +1,110 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <errno.h> #include <unistd.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#define MULTICAST_ADDR "224.0.0.1" -#define PORT 4532 -#define BUFFER_SIZE 1024 +#ifdef _WIN32 +#include <winsock2.h> +#include <ws2tcpip.h> +#pragma comment(lib, "Ws2_32.lib") +#else +#include <arpa/inet.h> +#include <netinet/in.h> +#include <sys/socket.h> +#include <sys/types.h> +#endif + +#define MCAST_PORT 4532 +#define MCAST_ADDR "224.0.0.1" +#define BUFFER_SIZE 4096 int main() { - // Create a UDP socket - int sock = socket(AF_INET, SOCK_DGRAM, 0); + int sock; + struct sockaddr_in mcast_addr; + char buffer[BUFFER_SIZE]; + int bytes_received; - if (sock < 0) +#ifdef _WIN32 + WSADATA wsaData; + + if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) { - perror("socket creation failed"); + fprintf(stderr, "WSAStartup failed: %d\n", WSAGetLastError()); + return 1; + } + +#endif + + if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) + { + perror("socket() failed"); exit(EXIT_FAILURE); } // Set the SO_REUSEADDR option to allow multiple processes to use the same address int optval = 1; - if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) < 0) + if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &optval, + sizeof(optval)) < 0) { - perror("setsockopt failed"); + //rig_debug(RIG_DEBUG_ERR, "%s: setsockopt: %s\n", __func__, strerror(errno)); + //return -RIG_EIO; + return 1; + } + + + memset(&mcast_addr, 0, sizeof(mcast_addr)); + mcast_addr.sin_family = AF_INET; + mcast_addr.sin_port = htons(MCAST_PORT); + mcast_addr.sin_addr.s_addr = htonl(INADDR_ANY); + + if (bind(sock, (struct sockaddr *)&mcast_addr, sizeof(mcast_addr)) < 0) + { + perror("bind() failed"); exit(EXIT_FAILURE); } - // Bind the socket to any available local address and the specified port - struct sockaddr_in addr = {0}; - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = htonl(INADDR_ANY); - addr.sin_port = htons(PORT); + struct ip_mreq mreq; - if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) - { - perror("bind failed"); - exit(EXIT_FAILURE); - } + mreq.imr_multiaddr.s_addr = inet_addr(MCAST_ADDR); - // Construct the multicast group address - struct ip_mreq mreq = {0}; - mreq.imr_multiaddr.s_addr = inet_addr(MULTICAST_ADDR); mreq.imr_interface.s_addr = htonl(INADDR_ANY); - // Join the multicast group - if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) + if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&mreq, + sizeof(mreq)) < 0) { - perror("setsockopt failed"); + perror("setsockopt() failed"); exit(EXIT_FAILURE); } - // Receive multicast packets in a loop while (1) { - char buffer[BUFFER_SIZE]; - struct sockaddr_in src_addr = {0}; - socklen_t addrlen = sizeof(src_addr); - ssize_t num_bytes = recvfrom(sock, buffer, BUFFER_SIZE - 1, 0, - (struct sockaddr *)&src_addr, &addrlen); + bytes_received = recvfrom(sock, buffer, BUFFER_SIZE, 0, NULL, 0); - if (num_bytes < 0) + if (bytes_received < 0) { - perror("recvfrom failed"); - exit(EXIT_FAILURE); + perror("recvfrom() failed"); + break; } - buffer[num_bytes] = '\0'; - printf("Received %zd bytes from %s:%d\n%s\n", num_bytes, - inet_ntoa(src_addr.sin_addr), ntohs(src_addr.sin_port), buffer); + buffer[bytes_received] = '\0'; + printf("Received: %s\n", buffer); } - // Leave the multicast group - if (setsockopt(sock, IPPROTO_IP, IP_DROP_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) + // Drop membership before closing the socket + if (setsockopt(sock, IPPROTO_IP, IP_DROP_MEMBERSHIP, (char *)&mreq, + sizeof(mreq)) < 0) { - perror("setsockopt failed"); - exit(EXIT_FAILURE); + perror("setsockopt() failed"); } - // Close the socket close(sock); +#ifdef _WIN32 + WSACleanup(); +#endif return 0; } +