hawxgamer

multicast sender and receiver posix c

Oct 14th, 2014
284
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.54 KB | None | 0 0
  1. #include <sys/types.h>
  2. #include <sys/socket.h>
  3. #include <netinet/in.h>
  4. #include <arpa/inet.h>
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include <unistd.h>
  9. #include <ctype.h>
  10. #include <sys/time.h>
  11. #include <fcntl.h>
  12.  
  13.  
  14. #define MAX_LEN 20
  15.  
  16.  
  17. static int flag_on = 1;
  18. static struct sockaddr_in multicast_addr;
  19. static char message_received[MAX_LEN+1];
  20. static int msgrecv_len;
  21. static struct ip_mreq mc_req;
  22. static char* multicast_ip="224.5.6.7";
  23. static unsigned short multicast_port=5006;
  24. static struct sockaddr_in from_addr;
  25. static unsigned int from_len;
  26.  
  27. static char message_to_send[MAX_LEN];
  28. static unsigned int send_len;
  29. static unsigned char multicast_ttl=1;
  30. static struct sockaddr_in multicast_addr;
  31. int sock; /* The socket file descriptor for our "listening"
  32. socket */
  33. int connectlist[5]; /* Array of connected sockets so we know who
  34. we are talking to */
  35. fd_set socks; /* Socket file descriptors we want to wake
  36. up for, using select() */
  37. int highsock; /* Highest #'d file descriptor, needed for select() */
  38.  
  39. void setnonblocking(sock)
  40. int sock;
  41. {
  42. int opts;
  43.  
  44. opts = fcntl(sock,F_GETFL);
  45. if (opts < 0)
  46. {
  47. perror("fcntl(F_GETFL)");
  48. exit(EXIT_FAILURE);
  49. }
  50. opts = (opts | O_NONBLOCK);
  51. if (fcntl(sock,F_SETFL,opts) < 0)
  52. {
  53. perror("fcntl(F_SETFL)");
  54. exit(EXIT_FAILURE);
  55. }
  56. return;
  57. }
  58.  
  59. void build_select_list()
  60. {
  61. int listnum; /* Current item in connectlist for for loops */
  62.  
  63. /* First put together fd_set for select(), which will
  64. consist of the sock veriable in case a new connection
  65. is coming in, plus all the sockets we have already
  66. accepted. */
  67.  
  68.  
  69. /* FD_ZERO() clears out the fd_set called socks, so that
  70. it doesn't contain any file descriptors. */
  71.  
  72. FD_ZERO(&socks);
  73.  
  74. /* FD_SET() adds the file descriptor "sock" to the fd_set,
  75. so that select() will return if a connection comes in
  76. on that socket (which means you have to do accept(), etc. */
  77.  
  78. FD_SET(sock,&socks);
  79.  
  80. /* Loops through all the possible connections and adds
  81. those sockets to the fd_set */
  82.  
  83. for (listnum = 0; listnum < 5; listnum++)
  84. {
  85. if (connectlist[listnum] != 0)
  86. {
  87. FD_SET(connectlist[listnum],&socks);
  88. if (connectlist[listnum] > highsock)
  89. highsock = connectlist[listnum];
  90. }
  91. }
  92. }
  93.  
  94. void deal_with_data(
  95. int listnum /* Current item in connectlist for for loops */
  96. )
  97. {
  98.  
  99. /* set the TTL (time to live/hop count) for the send */
  100. if ((setsockopt(sock, IPPROTO_IP, IP_MULTICAST_TTL, (void*) &multicast_ttl, sizeof(multicast_ttl))) < 0)
  101. {
  102. perror("setsockopt() failed");
  103. exit(1);
  104. }
  105.  
  106.  
  107. memset(&multicast_addr, 0, sizeof(multicast_addr));
  108. multicast_addr.sin_family = AF_INET;
  109. multicast_addr.sin_addr.s_addr = inet_addr(multicast_ip);
  110. multicast_addr.sin_port = htons(multicast_port);
  111.  
  112. //printf("Type the message below (Press Enter to send, ctrl-C to quit):\n");
  113. printf("NOW IN STATE SENDER!\n");
  114.  
  115. memset(message_to_send, 0, sizeof(message_to_send));
  116.  
  117. //while (fgets(message_to_send, MAX_LEN, stdin))
  118.  
  119. //message_to_send="batman";
  120. strcpy(message_to_send,"Hallo\n\0");
  121. printf("message to send: %s \n", message_to_send);
  122. send_len = strlen(message_to_send);
  123.  
  124. if ((sendto(sock, message_to_send, send_len, 0,
  125. (struct sockaddr *) &multicast_addr,
  126. sizeof(multicast_addr))) != send_len)
  127. {
  128. perror("Error in number of bytes");
  129. exit(1);
  130. }
  131.  
  132. memset(message_to_send, 0, sizeof(message_to_send));
  133. }
  134.  
  135. void read_socks()
  136. {
  137. memset(message_received, 0, sizeof(message_received));
  138. from_len = sizeof(from_addr);
  139. memset(&from_addr, 0, from_len);
  140.  
  141. /* block waiting to receive a packet */
  142. if ((msgrecv_len = recvfrom(sock, message_received, MAX_LEN, 0, (struct sockaddr*)&from_addr, &from_len)) < 0)
  143. {
  144. perror("recvfrom() failed");
  145. //break;
  146. }
  147.  
  148. printf("Received %d bytes from %s: ", msgrecv_len, inet_ntoa(from_addr.sin_addr));
  149. printf("%s", message_received);
  150. if(strstr(message_received,"haha\0")!=0)
  151. {
  152. printf("wuhuu");
  153. deal_with_data(1);
  154. }
  155.  
  156. }
  157.  
  158. int main (argc, argv)
  159. int argc;
  160. char *argv[];
  161. {
  162. char *ascport; /* ASCII version of the server port */
  163. int port; /* The port number after conversion from ascport */
  164. struct sockaddr_in multicast_addr; /* bind info structure */
  165. int reuse_addr = 1; /* Used so we can re-bind to our port
  166. while a previous connection is still
  167. in TIME_WAIT state. */
  168. struct timeval timeout; /* Timeout for select */
  169. int readsocks; /* Number of sockets ready for reading */
  170.  
  171. /* Make sure we got a port number as a parameter */
  172.  
  173.  
  174. /* Obtain a file descriptor for our "listening" socket */
  175. if ((sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
  176. {
  177. perror("socket() failed");
  178. exit(1);
  179. }
  180. /* So that we can re-bind to it without TIME_WAIT problems */
  181. setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &reuse_addr,
  182. sizeof(reuse_addr));
  183.  
  184. /* Set socket to non-blocking with our setnonblocking routine */
  185. setnonblocking(sock);
  186.  
  187. /* Get the address information, and bind it to the socket */
  188. //ascport = argv[1]; /* Read what the user gave us */
  189. //port = atoport(ascport); /* Use function from sockhelp to
  190. // convert to an int */
  191. memset((char *) &multicast_addr, 0, sizeof(multicast_addr));
  192. multicast_addr.sin_family = AF_INET;
  193. multicast_addr.sin_addr.s_addr = htonl(INADDR_ANY);
  194. multicast_addr.sin_port = htons(multicast_port);
  195.  
  196.  
  197. /* bind to multicast address to socket */
  198. if ((bind(sock, (struct sockaddr *) &multicast_addr, sizeof(multicast_addr))) < 0)
  199. {
  200. perror("bind() failed");
  201. exit(1);
  202. }
  203.  
  204. /* construct an IGMP join request structure */
  205. mc_req.imr_multiaddr.s_addr = inet_addr(multicast_ip);
  206. mc_req.imr_interface.s_addr = htonl(INADDR_ANY);
  207.  
  208. /* send an ADD MEMBERSHIP message via setsockopt */
  209. if ((setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void*) &mc_req, sizeof(mc_req))) < 0)
  210. {
  211. perror("setsockopt() failed");
  212. exit(1);
  213. }
  214.  
  215. /* Set up queue for incoming connections. */
  216. listen(sock,5);
  217.  
  218. /* Since we start with only one socket, the listening socket,
  219. it is the highest socket so far. */
  220. highsock = sock;
  221. memset((char *) &connectlist, 0, sizeof(connectlist));
  222.  
  223. while (1) /* Main server loop - forever */
  224. {
  225. build_select_list();
  226. timeout.tv_sec = 1;
  227. timeout.tv_usec = 0;
  228.  
  229. /* The first argument to select is the highest file
  230. descriptor value plus 1. In most cases, you can
  231. just pass FD_SETSIZE and you'll be fine. */
  232.  
  233. /* The second argument to select() is the address of
  234. the fd_set that contains sockets we're waiting
  235. to be readable (including the listening socket). */
  236.  
  237. /* The third parameter is an fd_set that you want to
  238. know if you can write on -- this example doesn't
  239. use it, so it passes 0, or NULL. The fourth parameter
  240. is sockets you're waiting for out-of-band data for,
  241. which usually, you're not. */
  242.  
  243. /* The last parameter to select() is a time-out of how
  244. long select() should block. If you want to wait forever
  245. until something happens on a socket, you'll probably
  246. want to pass NULL. */
  247.  
  248. readsocks = select(highsock+1, &socks, (fd_set *) 0,
  249. (fd_set *) 0, &timeout);
  250.  
  251. /* select() returns the number of sockets that had
  252. things going on with them -- i.e. they're readable. */
  253.  
  254. /* Once select() returns, the original fd_set has been
  255. modified so it now reflects the state of why select()
  256. woke up. i.e. If file descriptor 4 was originally in
  257. the fd_set, and then it became readable, the fd_set
  258. contains file descriptor 4 in it. */
  259.  
  260. if (readsocks < 0)
  261. {
  262. perror("select");
  263. exit(EXIT_FAILURE);
  264. }
  265. if (readsocks == 0)
  266. {
  267. /* Nothing ready to read, just show that
  268. we're alive */
  269. printf(".");
  270. fflush(stdout);
  271. }
  272. else
  273. read_socks();
  274. } /* while(1) */
  275. } /* main */
Advertisement
Add Comment
Please, Sign In to add comment