Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

178 lines
5.3 KiB

  1. /*++
  2. Copyright (c) 2000, Microsoft Corporation
  3. Module Name:
  4. mcastloop.c
  5. Abstract:
  6. This module demonstrates the working of loopback support for IP multicast.
  7. It consists of a main thread which joins a multicast group and listens
  8. for messages, as well as a sending thread which sends to the same group.
  9. Author:
  10. Abolade Gbadegesin (aboladeg) 3-March-2000
  11. Revision History:
  12. --*/
  13. #include <winsock2.h>
  14. #include <ws2tcpip.h>
  15. #include <windows.h>
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. ULONG LocalAddress;
  19. ULONG MulticastAddress;
  20. USHORT MulticastPort;
  21. ULONG WINAPI
  22. SendThread(
  23. PVOID Unused
  24. )
  25. {
  26. SOCKADDR_IN SockAddr;
  27. SOCKET Socket;
  28. //
  29. // Create a new UDP socket, bind it to any local IP address,
  30. // and set the multicast interface on which to receive messages.
  31. //
  32. Socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
  33. SockAddr.sin_family = AF_INET;
  34. SockAddr.sin_port = 0;
  35. SockAddr.sin_addr.s_addr = INADDR_ANY;
  36. if (bind(
  37. Socket, (PSOCKADDR)&SockAddr, sizeof(SOCKADDR_IN)
  38. ) == SOCKET_ERROR) {
  39. printf("SendThread: bind: %d\n", WSAGetLastError());
  40. } else {
  41. if (setsockopt(
  42. Socket, IPPROTO_IP, IP_MULTICAST_IF, (PCHAR)&LocalAddress,
  43. sizeof(LocalAddress)
  44. ) == SOCKET_ERROR) {
  45. printf("SendThread: setsockopt: %d\n", WSAGetLastError());
  46. } else {
  47. ULONG i;
  48. CHAR Buffer[64];
  49. //
  50. // Generate messages until interrupted.
  51. //
  52. SockAddr.sin_port = MulticastPort;
  53. SockAddr.sin_addr.s_addr = MulticastAddress;
  54. for (i = 0;; i++, Sleep(1000)) {
  55. sprintf(Buffer, "Text string %d.", i);
  56. if (sendto(
  57. Socket, Buffer, sizeof(Buffer), 0,
  58. (PSOCKADDR)&SockAddr, sizeof(SockAddr)
  59. ) == SOCKET_ERROR) {
  60. printf("SendThread: sendto: %d\n", WSAGetLastError());
  61. } else {
  62. printf("SendThread: %s\n", Buffer);
  63. }
  64. }
  65. }
  66. }
  67. return 0;
  68. }
  69. int __cdecl
  70. main(
  71. int argc,
  72. char* argv[]
  73. )
  74. {
  75. HANDLE Handle;
  76. ULONG Length;
  77. SOCKET Socket;
  78. SOCKADDR_IN SockAddr;
  79. ULONG ThreadId;
  80. WSADATA wd;
  81. //
  82. // Check arguments, initialize Windows Sockets, and bind it to the local
  83. // IP address specified as the multicast source interface.
  84. //
  85. if (argc != 3) {
  86. printf("Usage: %s <local IP address> <multicast IP address>\n", argv[0]);
  87. return 0;
  88. }
  89. WSAStartup(0x202, &wd);
  90. Socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
  91. SockAddr.sin_family = AF_INET;
  92. SockAddr.sin_port = 0;
  93. SockAddr.sin_addr.s_addr = inet_addr(argv[1]);
  94. if (bind(
  95. Socket, (PSOCKADDR)&SockAddr, sizeof(SOCKADDR_IN)
  96. ) == SOCKET_ERROR) {
  97. printf("bind: %d\n", WSAGetLastError());
  98. } else {
  99. //
  100. // Retrieve the local IP address selected for the socket,
  101. // and use it to request multicast group membership.
  102. //
  103. Length = sizeof(SOCKADDR_IN);
  104. if (getsockname(
  105. Socket, (PSOCKADDR)&SockAddr, &Length
  106. ) == SOCKET_ERROR) {
  107. printf("getsockname: %d\n", WSAGetLastError());
  108. } else {
  109. struct ip_mreq IpMreq;
  110. IpMreq.imr_multiaddr.s_addr = inet_addr(argv[2]);
  111. IpMreq.imr_interface.s_addr = INADDR_ANY;
  112. if (setsockopt(
  113. Socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, (PCHAR)&IpMreq,
  114. sizeof(IpMreq)
  115. ) == SOCKET_ERROR) {
  116. printf("setsockopt: %d\n", WSAGetLastError());
  117. } else {
  118. //
  119. // Start the thread which will send multicast packets,
  120. // and begin receiving input.
  121. //
  122. MulticastAddress = inet_addr(argv[2]);
  123. MulticastPort = SockAddr.sin_port;
  124. LocalAddress = SockAddr.sin_addr.s_addr;
  125. Handle = CreateThread(NULL, 0, SendThread, NULL, 0, &ThreadId);
  126. if (!Handle) {
  127. printf("CreateThread: %d\n", GetLastError());
  128. } else {
  129. CHAR Buffer[576];
  130. ULONG BufferLength;
  131. CloseHandle(Handle);
  132. for (;; Sleep(1000)) {
  133. Length = sizeof(SOCKADDR_IN);
  134. ZeroMemory(Buffer, sizeof(Buffer));
  135. BufferLength =
  136. recvfrom(
  137. Socket, Buffer, sizeof(Buffer), 0,
  138. (PSOCKADDR)&SockAddr, &Length
  139. );
  140. if (BufferLength == SOCKET_ERROR) {
  141. printf("recvfrom: %d\n", WSAGetLastError());
  142. } else {
  143. printf("ReceiveThread: %s\n", Buffer);
  144. }
  145. }
  146. }
  147. }
  148. }
  149. }
  150. closesocket(Socket);
  151. return 0;
  152. }