/* jednoduchy chat s multicastem * * Radek Brich, 7.11.2004 */ #include #include #include #include #include #define TRUE 1 #define FALSE 0 #define BUF_SIZE 1024 #define MCAST_ADDR "231.23.45.67" #define CHAT_PORT 3500 #define TTL_VALUE 1 #define LOOPBACK TRUE int main(int argc, char *argv[]) { int sock; /* socket pro zapis i cteni */ int i; /* pomocna promenna */ struct sockaddr_in sa_local, /* adresa lokalniho rozhrani */ sa_dest, /* adresa prijemce pro zapis */ sa_src; /* adresa odesilatele při cteni */ int sa_size = sizeof(struct sockaddr_in); struct ip_mreq mreq; pid_t pid; /* novy UDP socket */ sock = socket(AF_INET, SOCK_DGRAM, 0); /* povolit vice procesum pouzit stejnou adresu */ i = TRUE; setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i)); /* socket pripojime k sitovemu rozhrani */ sa_local.sin_family = AF_INET; sa_local.sin_addr.s_addr = htonl(INADDR_ANY); sa_local.sin_port = htons(CHAT_PORT); bind(sock, (struct sockaddr*) &sa_local, sizeof(sa_local)); /* pripojeni k multicastove skupine */ mreq.imr_multiaddr.s_addr = inet_addr(MCAST_ADDR); mreq.imr_interface.s_addr = INADDR_ANY; setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)); /* nastavime hodnotu TTL - urcuje, jak daleko bude packet smerovan */ i = TTL_VALUE; setsockopt(sock, IPPROTO_IP, IP_MULTICAST_TTL, &i, sizeof(i)); /* loopback */ i = LOOPBACK; setsockopt(sock, IPPROTO_IP, IP_MULTICAST_LOOP, &i, sizeof(i)); /* adresa pro vysilani (= adresa multicastove skupiny) */ sa_dest.sin_family = AF_INET; sa_dest.sin_addr.s_addr = inet_addr(MCAST_ADDR); sa_dest.sin_port = htons(CHAT_PORT); if ((pid = fork()) > 0) { /* RODIC */ char msg[BUF_SIZE]; for(;;) { /* prijima data z multicastove skupiny a tiskne je na stdout */ i = recvfrom(sock, msg, BUF_SIZE, 0, (struct sockaddr* )&sa_src, &sa_size); if (i < 0) { perror("* recvfrom() failed\n"); exit(1); } printf("[%s] %s", inet_ntoa(sa_src.sin_addr), msg); } } else if (pid == 0) { /* POTOMEK */ char msg[BUF_SIZE]; for(;;) { /* vysila text z stdin multicastem */ fgets(msg, BUF_SIZE, stdin); i = sendto(sock, msg, strlen(msg)+1, 0, (struct sockaddr*) &sa_dest, sa_size); if (i < 0) { perror("* sendto() failed\n"); exit(1); } } } else err(1, "fork()"); close(sock); return(0); }