#include #include #include #include #include #include #include #include #include "list.h" #include #include #define LISTENING_PORT 1337 #define LISTENING_GROUP "224.0.0.42" #define BUFLEN 512 main(int argc) { struct sockaddr_in addr, tcpaddr; int addrlen, tcpaddrlen, sock, tcpsock, cnt, maxfd, res, tcpport, newsock; struct ip_mreq mreq; char message[BUFLEN]; fd_set rset; List sockets; Position pos; //create the multicast udp socket to use sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); //throw error when the multicast socket couldn't be opened if(sock<0) { perror("Socket couldn't be opened"); exit(1); } //create the tcp communication socket to use tcpsock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); //throw error when the multicast socket couldn't be opened if(tcpsock<0) { perror("TCP socket couldn't be opened"); exit(1); } //fill string with zeros bzero((char *)&tcpaddr, sizeof(tcpaddr)); //set the socket-family to ipv4 protocolfamily tcpaddr.sin_family = AF_INET; //enter the address of the host we're running on into the struct tcpaddr.sin_addr.s_addr = htonl(INADDR_ANY); //calculate the size of the address tcpaddrlen = sizeof(tcpaddr); //fill string with zeros bzero((char *)&addr, sizeof(addr)); //set the socket-family to ipv4 protocolfamily addr.sin_family = AF_INET; //enter the address of the host we're running on into the struct addr.sin_addr.s_addr = htonl(INADDR_ANY); //calculate the size of the address addrlen = sizeof(addr); //enter the port to listen on into the struct addr.sin_port = htons(LISTENING_PORT); //bind the tcp communication socket to the address used if(bind(tcpsock, (struct sockaddr *)&tcpaddr, sizeof(tcpaddr))<0) { perror("Couldn't bind the multicast socket"); exit(1); } //start to listen on that socket if(listen(tcpsock,10)<0) { perror("Couldn't listen on that socket"); exit(1); } //bind the multicast socket to the address used if(bind(sock, (struct sockaddr *)&addr, sizeof(addr))<0) { perror("Couldn't bind the multicast socket"); exit(1); } //get the assigned port for the tcp communication socket if(getsockname(tcpsock, (struct sockaddr *)&tcpaddr, &tcpaddrlen)<0) { perror("Couldn't get the socketname"); exit(1); } tcpport = tcpaddr.sin_port; printf("The TCP communication socket port is: %d\n",tcpport); //create the linked list to save the sockets sockets = MakeEmpty(NULL); pos = Header(sockets); Insert(sock, sockets, pos); Insert(tcpsock, sockets, pos); //set the address of the multicast group that we want to listen to mreq.imr_multiaddr.s_addr = inet_addr(LISTENING_GROUP); //set the address on which we will try to join the multicast group to the interface mreq.imr_interface.s_addr = htonl(INADDR_ANY); //request to join the multicast group to the interface if(setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq))<0) { perror("Couldn't set the socket options for mreq"); exit(1); } //start to listen to clients searching for the server through the multicast group while(1) { FD_ZERO(&rset); pos = Header(sockets); maxfd = 0; do { pos = Advance(pos); FD_SET(Retrieve(pos),&rset); if(Retrieve(pos)>maxfd) maxfd = Retrieve(pos); printf("pos is: %d\n",Retrieve(pos)); } while(!IsLast(pos, sockets)); printf("Going to make a select() call\n"); printf("%d is maxfd\n",maxfd); res = select(maxfd+1,&rset,NULL,NULL,NULL); if(res<=0) { perror("Error while selecting a socket"); exit(1); } printf("Made the select() call\n"); if(FD_ISSET(sock,&rset)) { //try to receive a message sent to the multicast group including the information of who sent it cnt = recvfrom(sock, message, sizeof(message)-1, 0, (struct sockaddr *)&addr, &addrlen); //if there is an error reading from the socket, terminate //else if the result is 0, there was no message to read, break the loop and try again if(cnt<0) { perror("Error while trying to receive a message from the socket"); exit(1); } else if(cnt==0) { break; } message[cnt] = '\0'; printf("%s",message); bzero(message, sizeof(message)); sprintf(message, "discovery_reply %d\n",tcpport); if(sendto(sock,message,BUFLEN,0,(struct sockaddr *)&addr,addrlen)<0) { perror("Couldn't answer multicast request"); exit(1); } } if(FD_ISSET(tcpsock,&rset)) { printf("Accepting new connection"); newsock = accept(tcpsock,(struct sockaddr *)&tcpaddr, &tcpaddrlen); if(newsock<0) { perror("Couldn't create new socket"); exit(1); } Insert(newsock, sockets, pos); } pos = Header(sockets); while(!IsLast(pos, sockets)){ pos = Advance(pos); if((Retrieve(pos)!=sock)&&(Retrieve(pos)!=tcpsock)) { if(FD_ISSET(Retrieve(pos),&rset)) { cnt = recvfrom(Retrieve(pos), message, sizeof(message)-1, 0, (struct sockaddr *)&addr, &addrlen); if(cnt<0) { perror("Error while trying to receive a message from the socket"); exit(1); } message[cnt] = '\0'; printf("%s",message); } } } } }