?? mcastv3.cpp
字號:
rc = WSAIoctl(
s,
SIO_SET_MULTICAST_FILTER,
filterbuf,
filterlen,
NULL,
0,
&bytes,
NULL,
NULL
);
if (rc == SOCKET_ERROR)
{
fprintf(stderr, "JoinMulticastGroup: WSAIoctl: SIO_SET_MULTICAST_FILTER failed: %d\n",
WSAGetLastError());
return SOCKET_ERROR;
}
}
return NO_ERROR;
}
//
// Function: GetMulticastState
//
// Description:
// Obtains the current multicat filter state and prints it to the console.
//
void GetMulticastState(SOCKET s, struct addrinfo *group, struct addrinfo *iface)
{
struct ip_msfilter *filter=NULL;
char buf[15000];
int buflen=15000,
rc,
i;
filter = (struct ip_msfilter *)buf;
filter->imsf_multiaddr = ((SOCKADDR_IN *)group->ai_addr)->sin_addr;
filter->imsf_interface = ((SOCKADDR_IN *)iface->ai_addr)->sin_addr;
rc = WSAIoctl(s, SIO_GET_MULTICAST_FILTER, buf, buflen, buf, buflen, (LPDWORD)&buflen, NULL, NULL);
if (rc == SOCKET_ERROR)
{
fprintf(stderr, "GetMulticastState: WSAIoctl failed: %d\n", WSAGetLastError());
return;
}
printf("imsf_multiaddr = %s\n", inet_ntoa(filter->imsf_multiaddr));
printf("imsf_interface = %s\n", inet_ntoa(filter->imsf_interface));
printf("imsf_fmode = %s\n", (filter->imsf_fmode == MCAST_INCLUDE ? "MCAST_INCLUDE" : "MCAST_EXCLUDE"));
printf("imsf_numsrc = %d\n", filter->imsf_numsrc);
for(i=0; i < (int)filter->imsf_numsrc ;i++)
{
printf("imsf_slist[%d] = %s\n", i, inet_ntoa(filter->imsf_slist[i]));
}
return;
}
//
// Function: SetSendInterface
//
// Description:
// Set the send interface for the socket.
//
int SetSendInterface(SOCKET s, struct addrinfo *iface)
{
char *optval=NULL;
int optlevel,
option,
optlen,
rc;
optlevel = IPPROTO_IP;
option = IP_MULTICAST_IF;
optval = (char *) &((SOCKADDR_IN *)iface->ai_addr)->sin_addr.s_addr;
optlen = sizeof(((SOCKADDR_IN *)iface->ai_addr)->sin_addr.s_addr);
rc = setsockopt(
s,
optlevel,
option,
optval,
optlen
);
if (rc == SOCKET_ERROR)
{
printf("setsockopt failed: %d\n", WSAGetLastError());
}
else
{
printf("Set sending interface to: ");
PrintAddress(iface->ai_addr, iface->ai_addrlen);
printf("\n");
}
return rc;
}
//
// Function: SetMulticastTtl
//
// Description:
// This routine sets the multicast TTL on the socket.
//
int SetMulticastTtl(SOCKET s, int af, int ttl)
{
char *optval=NULL;
int optlevel,
option,
optlen,
rc;
optlevel = IPPROTO_IP;
option = IP_MULTICAST_TTL;
optval = (char *) &ttl;
optlen = sizeof(ttl);
rc = setsockopt(
s,
optlevel,
option,
optval,
optlen
);
if (rc == SOCKET_ERROR)
{
fprintf(stderr, "SetMulticastTtl: setsockopt failed: %d\n", WSAGetLastError());
}
else
{
printf("Set multicast ttl to: %d\n", ttl);
}
return rc;
}
//
// Function: SetMulticastLoopBack
//
// Description:
// This function enabled or disables multicast loopback. If loopback is enabled
// (and the socket is a member of the destination multicast group) then the
// data will be placed in the receive queue for the socket such that if a
// receive is posted on the socket its own data will be read. For this sample
// it doesn't really matter as if invoked as the sender, no data is read.
//
int SetMulticastLoopBack(SOCKET s, int af, int loopval)
{
char *optval=NULL;
int optlevel,
option,
optlen,
rc;
optlevel = IPPROTO_IP;
option = IP_MULTICAST_LOOP;
optval = (char *) &loopval;
optlen = sizeof(loopval);
rc = setsockopt(
s,
optlevel,
option,
optval,
optlen
);
if (rc == SOCKET_ERROR)
{
fprintf(stderr, "SetMulticastLoopBack: setsockopt failed: %d\n", WSAGetLastError());
}
else
{
printf("Setting multicast loopback to: %d\n", loopval);
}
return rc;
}
//
// Function: main
//
// Description:
// Parse the command line arguments, load the Winsock library,
// create a socket and join the multicast group. If set as a
// sender then begin sending messages to the multicast group;
// otherwise, call recvfrom() to read messages send to the
// group.
//
int _cdecl main(int argc, char **argv)
{
WSADATA wsd;
SOCKET s;
struct addrinfo *resmulti=NULL,
*resbind=NULL,
*resif=NULL;
char *buf;
int rc,
i=0;
// Parse the command line
ValidateArgs(argc, argv);
if ((gMode == MCAST_INCLUDE) && (gSourceCount == 0) && (!bUseFilter))
{
printf("\nNo sources specified!\n\n"
"At least one source must be specified when mode is INCLUDE\n"
" and not using the multicast filter option (-f)\n\n");
usage(argv[0]);
}
// Load Winsock
if (WSAStartup(MAKEWORD(1, 1), &wsd) != 0)
{
printf("WSAStartup failed\n");
return -1;
}
// Resolve the multicast address
resmulti = ResolveAddress(gMulticast, gPort, AF_UNSPEC, gSocketType, gProtocol);
if (resmulti == NULL)
{
fprintf(stderr, "Unable to convert multicast address '%s': %d\n",
gMulticast, WSAGetLastError());
return -1;
}
if (resmulti->ai_family != AF_INET)
{
fprintf(stderr, "Source multicasting is only supported for IPv4\n");
return -1;
}
// Resolve the binding address
resbind = ResolveAddress(gBindAddr, (bSender ? "0" : gPort), resmulti->ai_family, resmulti->ai_socktype, resmulti->ai_protocol);
if (resbind == NULL)
{
fprintf(stderr, "Unable to convert bind address '%s': %d\n",
gBindAddr, WSAGetLastError());
return -1;
}
if (resbind->ai_family != AF_INET)
{
fprintf(stderr, "Source multicasting is only supported for IPv4\n");
return -1;
}
// Resolve the multicast interface
resif = ResolveAddress(gInterface, "0", resmulti->ai_family, resmulti->ai_socktype, resmulti->ai_protocol);
if (resif == NULL)
{
fprintf(stderr, "Unable to convert interface address '%s': %d\n",
gInterface, WSAGetLastError());
return -1;
}
if (resif->ai_family != AF_INET)
{
fprintf(stderr, "Source multicasting is only supported for IPv4\n");
return -1;
}
//
// Create the socket. In Winsock 1 you don't need any special
// flags to indicate multicasting.
//
s = socket(resmulti->ai_family, resmulti->ai_socktype, resmulti->ai_protocol);
if (s == INVALID_SOCKET)
{
printf("socket failed with: %d\n", WSAGetLastError());
return -1;
}
printf("socket handle = 0x%p\n", s);
//
// Bind the socket to the local interface. This is done so we
// can receive data
//
rc = bind(s, resbind->ai_addr, resbind->ai_addrlen);
if (rc == SOCKET_ERROR)
{
printf("bind failed: %d\n", WSAGetLastError());
return -1;
}
printf("Binding to ");
PrintAddress(resbind->ai_addr, resbind->ai_addrlen);
printf("\n");
if (bDontJoin == FALSE)
{
rc = JoinMulticastGroup(s, resmulti, resif);
if (rc == SOCKET_ERROR)
{
return -1;
}
}
rc = SetSendInterface(s, resif);
if (rc == SOCKET_ERROR)
{
return -1;
}
// Set the TTL to something else. The default TTL is one.
rc = SetMulticastTtl(s, resmulti->ai_family, gTtl);
if (rc == SOCKET_ERROR)
{
return -1;
}
// Disable the loopback if selected. Note that on NT4 and Win95
// you cannot disable it.
if (bLoopBack)
{
rc = SetMulticastLoopBack(s, resmulti->ai_family, gLoopBack);
if (rc == SOCKET_ERROR)
{
return -1;
}
}
//
// When using sendto on an IPv6 multicast socket, the scope id needs
// to be zero.
//
if ((bSender) && (resmulti->ai_family == AF_INET6))
((SOCKADDR_IN6 *)resmulti->ai_addr)->sin6_scope_id = 0;
if (bConnect)
{
rc = connect(s, resmulti->ai_addr, resmulti->ai_addrlen);
if (rc == SOCKET_ERROR)
{
printf("connect failed: %d\n", WSAGetLastError());
return -1;
}
}
GetMulticastState(s, resmulti, resif);
buf = (char *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, gBufferSize);
if (buf == NULL)
{
fprintf(stderr, "HeapAlloc failed: %d\n", GetLastError());
return -1;
}
if (!bSender) // receiver
{
SOCKADDR_STORAGE safrom;
int fromlen;
//
for(i=0; i < gCount ;i++)
{
fromlen = sizeof(safrom);
rc = recvfrom(
s,
buf,
gBufferSize,
0,
(SOCKADDR *)&safrom,
&fromlen
);
if (rc == SOCKET_ERROR)
{
printf("recvfrom failed with: %d\n",
WSAGetLastError());
break;
}
printf("RECV %d bytes from <", rc);
PrintAddress((SOCKADDR *)&safrom, fromlen);
printf(">\n");
}
}
else // sender
{
memset(buf, '%', gBufferSize);
// Send some data
for(i=0; i < gCount ; i++)
{
rc = sendto(
s,
buf,
gBufferSize,
0,
resmulti->ai_addr,
resmulti->ai_addrlen
);
if (rc == SOCKET_ERROR)
{
printf("sendto failed with: %d\n", WSAGetLastError());
return -1;
}
printf("SENT %d bytes to ", rc);
PrintAddress(resmulti->ai_addr, resmulti->ai_addrlen);
printf("\n");
Sleep(500);
}
}
freeaddrinfo(resmulti);
freeaddrinfo(resbind);
freeaddrinfo(resif);
HeapFree(GetProcessHeap(), 0, buf);
closesocket(s);
WSACleanup();
return 0;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -