📄 mcastws1.cpp
字号:
optlen,
rc;
rc = NO_ERROR;
if (af == AF_INET)
{
// Set the options for V4
optlevel = IPPROTO_IP;
option = IP_MULTICAST_TTL;
optval = (char *) &ttl;
optlen = sizeof(ttl);
}
else if (af == AF_INET6)
{
// Set the options for V6
optlevel = IPPROTO_IPV6;
option = IPV6_MULTICAST_HOPS;
optval = (char *) &ttl;
optlen = sizeof(ttl);
}
else
{
fprintf(stderr, "Attemtping to set TTL for invalid address family!\n");
rc = SOCKET_ERROR;
}
if (rc != SOCKET_ERROR)
{
// Set the TTL value
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;
rc = NO_ERROR;
if (af == AF_INET)
{
// Set the v4 options
optlevel = IPPROTO_IP;
option = IP_MULTICAST_LOOP;
optval = (char *) &loopval;
optlen = sizeof(loopval);
}
else if (af == AF_INET6)
{
// Set the v6 options
optlevel = IPPROTO_IPV6;
option = IPV6_MULTICAST_LOOP;
optval = (char *) &loopval;
optlen = sizeof(loopval);
}
else
{
fprintf(stderr, "Attemtping to set multicast loopback for invalid address family!\n");
rc = SOCKET_ERROR;
}
if (rc != SOCKET_ERROR)
{
// Set the multpoint loopback
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=NULL;
int rc,
i=0;
// Parse the command line
ValidateArgs(argc, argv);
// 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;
}
// 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;
}
// 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;
}
//
// 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");
// Join the multicast group if specified
if (bDontJoin == FALSE)
{
rc = JoinMulticastGroup(s, resmulti, resif);
if (rc == SOCKET_ERROR)
{
return -1;
}
}
// Set the send (outgoing) interface
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;
}
}
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("read %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);
closesocket(s);
WSACleanup();
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -