📄 qosmcast.c
字号:
WSAEVENT hEvent;
WSABUF wbuf;
DWORD dwBytes=0,
dwFlags=0,
dwFromLen,
dwBytesRecv,
dwBytesSent;
QOS *lpqos=NULL;
char rcvbuf[DATA_BUFFER_SZ],
sndbuf[DATA_BUFFER_SZ],
qosbuf[QOS_BUFFER_SZ];
int ret,
i;
static BOOL bOkToSend=FALSE;
//
// Create the event used to signal socket events
//
hEvent = WSACreateEvent();
if (hEvent == WSA_INVALID_EVENT)
{
printf("WSACreateEvent() failed: %d\n", WSAGetLastError());
return;
}
local.sin_family = AF_INET;
local.sin_port = htons(5150);
local.sin_addr.s_addr = htonl(INADDR_ANY);
ret = bind(s, (SOCKADDR *)&local, sizeof(local));
if (ret == SOCKET_ERROR)
{
printf("bind() failed: %d\n", WSAGetLastError());
return;
}
// Check to see if we're supposed to set QOS before joining the
// multicast group or if we just want to enabled FD_QOS on the
// socket.
//
lpqos = NULL;
if (iSetQos == SET_QOS_BEFORE)
{
if (bSender)
lpqos = &sendQos;
else
lpqos = &recvQos;
//
// Call this routine to set QOS for both senders and receivers.
// In the case of senders, no provider specific objects are used.
//
if (SetQosReceivers(s, lpqos) == FALSE)
return;
lpqos = NULL;
}
else if (iSetQos == SET_QOS_EVENT)
{
// Only want to receive the FD_QOS event and set QOS
// at a later time.
//
if (bSender)
{
lpqos = &sendQos;
sendQos.SendingFlowspec.ServiceType =
sendQos.SendingFlowspec.ServiceType;
}
else
{
lpqos = &recvQos;
recvQos.ReceivingFlowspec.ServiceType =
recvQos.ReceivingFlowspec.ServiceType;
}
if (SetQosReceivers(s, lpqos) == FALSE)
return;
lpqos = NULL;
}
else if (iSetQos == SET_QOS_DURING)
{
if (bSender)
lpqos = &sendQos;
else
lpqos = &recvQos;
//
// If setting QOS in the WSAJoinLeaf call we need to set
// the RSVP_RESERVE_INFO structure beforehand.
//
if (iNumSenders > 0)
SetQosReserveInfo(lpqos);
}
else
lpqos = NULL;
// Setup the flags to indicate whether we are sending or receiving
//
if (bSender)
dwFlags = JL_SENDER_ONLY;
else
dwFlags = JL_RECEIVER_ONLY;
for(i=0; i < iNumGroups ;i++)
{
// Setup the mutlicast address structure which will be used
// throughout this function.
//
mcast.sin_family = AF_INET;
mcast.sin_port = htons(5150);
mcast.sin_addr.s_addr = inet_addr(szMulticastAddrs[i]);
//
// Join the multicast group!
//
ret = WSAJoinLeaf(s, (SOCKADDR *)&mcast, sizeof(mcast), NULL, NULL,
lpqos, NULL, dwFlags);
if (ret == SOCKET_ERROR)
{
printf("WSAJoinLeaf() failed: %d\n", WSAGetLastError());
return;
}
}
if (lpqos)
PrintQos(lpqos);
if (iSetQos == SET_QOS_AFTER)
{
// Setting QOS after joining the group. Since WSAJoinLeaf does
// an implicit bind, we only have to call SIO_SET_QOS.
//
if (bSender)
lpqos = &sendQos;
else
lpqos = &recvQos;
if (SetQosReceivers(s, lpqos) == FALSE)
return;
}
// Register for the events we want to receive
//
ret = WSAEventSelect(s, hEvent, FD_QOS | FD_READ | FD_WRITE);
if (ret == SOCKET_ERROR)
{
printf("WSAEventSelect() failed: %d\n", WSAGetLastError());
return;
}
// Loop until done!
//
while (1)
{
// Wait until an event shows up
//
ret = WSAWaitForMultipleEvents(1, &hEvent, FALSE, WSA_INFINITE, FALSE);
if (ret == WSA_WAIT_FAILED)
{
printf("WSAWaitForMultipleEvents() failed: %d\n",
WSAGetLastError());
return;
}
// Enumerate any events that have occured.
//
ret = WSAEnumNetworkEvents(s, hEvent, &ne);
if (ret == SOCKET_ERROR)
{
printf("WSAEnumNetworkEvents() failed: %d\n", WSAGetLastError());
return;
}
if (ne.lNetworkEvents & FD_READ)
{
// Got a FD_READ event. Check for errors and then read pending data.
//
if (ne.iErrorCode[FD_READ_BIT])
{
printf("FD_READ error: %d\n", ne.iErrorCode[FD_READ_BIT]);
}
dwFromLen = sizeof(from);
wbuf.buf = rcvbuf;
wbuf.len = DATA_BUFFER_SZ;
dwFlags = 0;
ret = WSARecvFrom(s, &wbuf, 1, &dwBytesRecv, &dwFlags, (SOCKADDR *)&from,
&dwFromLen, NULL, NULL);
if (ret == SOCKET_ERROR)
{
printf("WSARecvFrom() failed: %d\n", WSAGetLastError());
return;
}
rcvbuf[dwBytesRecv] = 0;
printf("READ [%s] from [%s]\n", rcvbuf, inet_ntoa(from.sin_addr));
}
if (ne.lNetworkEvents & FD_WRITE)
{
// Got an FD_WRITE event. If we're the sender check to see if
// we're waiting for confirmation before sending..if so don't send
// until such a time.
//
if (ne.iErrorCode[FD_WRITE_BIT])
{
printf("FD_WRITE error: %d\n", ne.iErrorCode[FD_WRITE_BIT]);
}
if ((bSender) && (!bWaitToSend))
{
memset(sndbuf, '#', DATA_BUFFER_SZ);
wbuf.buf = sndbuf;
wbuf.len = DATA_BUFFER_SZ - 1;
for(i=0; i < iNumGroups ;i++)
{
mcast.sin_family = AF_INET;
mcast.sin_port = htons(5150);
mcast.sin_addr.s_addr = inet_addr(szMulticastAddrs[i]);
ret = WSASendTo(s, &wbuf, 1, &dwBytesSent, 0, (SOCKADDR *)&mcast,
sizeof(mcast), NULL, NULL);
if (ret == SOCKET_ERROR)
{
printf("WSASendTo() failed: %d\n", WSAGetLastError());
return;
}
printf("WSASendTo() wrote: %d bytes to %s\n", dwBytesSent,
inet_ntoa(mcast.sin_addr));
}
}
}
if (ne.lNetworkEvents & FD_QOS)
{
// Got an FD_QOS event. This can be triggered by a great
// variety of things. Typically if an error code is set it is
// actually more of a status such as notification that there
// are senders or receivers out there so we need to check
// for quite a few "error" codes to make sure we're doing
// the right thing.
//
bOkToSend = FALSE;
printf("FD_QOS event\n");
if (ne.iErrorCode[FD_QOS_BIT])
{
switch (ne.iErrorCode[FD_QOS_BIT])
{
case WSA_QOS_RECEIVERS:
printf("\tQOS recievers\n");
bOkToSend = TRUE;
break;
case WSA_QOS_SENDERS:
printf("\tQOS senders\n");
break;
case WSA_QOS_NO_SENDERS:
printf("\tQOS no senders\n");
break;
case WSA_QOS_NO_RECEIVERS:
printf("\tQOS no receivers\n");
break;
case WSA_QOS_REQUEST_CONFIRMED:
printf("\tQOS request confirmed\n");
break;
case WSA_QOS_ADMISSION_FAILURE:
printf("\tQOS admission failure\n");
return;
case WSA_QOS_POLICY_FAILURE:
printf("\tQOS policy failure\n");
return;
case WSA_QOS_BAD_STYLE:
printf("\tQOS bad style\n");
return;
case WSA_QOS_BAD_OBJECT:
printf("\tQOS bad object\n");
return;
case WSA_QOS_TRAFFIC_CTRL_ERROR:
printf("\tQOS traffic control error\n");
return;
case WSA_QOS_GENERIC_ERROR:
printf("\tQOS generic error\n");
return;
default:
printf("FD_QOS error: %d\n", ne.iErrorCode[FD_QOS_BIT]);
return;
}
}
lpqos = (QOS *)qosbuf;
lpqos->ProviderSpecific.buf = &qosbuf[sizeof(QOS)];
lpqos->ProviderSpecific.len = sizeof(qosbuf) - sizeof(QOS);
ret = WSAIoctl(s, SIO_GET_QOS, NULL, 0, lpqos, QOS_BUFFER_SZ,
&dwBytes, NULL, NULL);
if (ret == SOCKET_ERROR)
{
printf("WSAIoctl() failed: %d\n", WSAGetLastError());
return;
}
PrintQos(lpqos);
//
// If we're the sender and we've specified to wait for confirmation
// before sending not only do we need to check the error code checked
// earlier, but it is possible to return status information in the
// provider specific buffer so we check that too.
//
if (bSender)
{
if (ChkForQosStatus(lpqos, WSA_QOS_RECEIVERS))
bOkToSend = TRUE;
//
// If we got confirmation, send data
//
if (bWaitToSend && bOkToSend)
{
memset(sndbuf, '@', DATA_BUFFER_SZ);
wbuf.buf = sndbuf;
wbuf.len = DATA_BUFFER_SZ - 1;
for(i=0; i < iNumGroups ;i++)
{
mcast.sin_family = AF_INET;
mcast.sin_port = htons(5150);
mcast.sin_addr.s_addr = inet_addr(szMulticastAddrs[i]);
ret = WSASendTo(s, &wbuf, 1, &dwBytesSent, 0, (SOCKADDR *)&mcast,
sizeof(mcast), NULL, NULL);
if (ret == SOCKET_ERROR)
{
printf("WSASendTo() failed: %d\n", WSAGetLastError());
return;
}
printf("WSASendTo() wrote: %d bytes to %s\n", dwBytesSent,
inet_ntoa(mcast.sin_addr));
}
}
}
}
}
return;
}
//
// Function: main
//
// Description:
// Parse command line arguments, find a QOS enabled provider that
// supports multicasting, create a socket, and call the driver
// function.
//
int main(int argc, char **argv)
{
WSAPROTOCOL_INFO *pi=NULL;
WSADATA wsd;
SOCKET s;
// Parse command line args and initialize Winsock.
//
ValidateArgs(argc, argv);
if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)
{
printf("WSAStartup() failed: %d\n", GetLastError());
return -1;
}
// Find a provider that supports QOS and multicasting.
//
pi = FindProtocolInfo(AF_INET, SOCK_DGRAM, IPPROTO_UDP,
XP1_QOS_SUPPORTED | XP1_SUPPORT_MULTIPOINT);
if (!pi)
{
printf("unable to find suitable provider!\n");
WSACleanup();
return -1;
}
printf("Provider returned: %s\n", pi->szProtocol);
//
// Create a socket.
//
s = WSASocket(FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO,
FROM_PROTOCOL_INFO, pi, 0, WSA_FLAG_OVERLAPPED |
WSA_FLAG_MULTIPOINT_C_LEAF | WSA_FLAG_MULTIPOINT_D_LEAF);
if (s == SOCKET_ERROR)
{
printf("WSASocket() failed: %d\n", WSAGetLastError());
WSACleanup();
return -1;
}
// Initialize the sending and receiving QOS structures
//
InitQos();
MulticastDriver(s);
closesocket(s);
WSACleanup();
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -