📄 qosudp.c
字号:
// Function: SetQosReceivers
//
// Description:
// This function sets the RSVP_RESERVE_INFO provider specific
// object if a different filter has been specified along with
// the sender's IP address. It then calls SIO_SET_QOS to set
// the supplied QOS parameters on the socket.
//
BOOL SetQosReceivers(SOCKET s, QOS *lpqos)
{
int ret;
DWORD dwBytes,
dwSize;
if (iNumSenders > 0)
{
SetQosReserveInfo(lpqos);
dwSize = sizeof(QOS) + sizeof(RSVP_RESERVE_INFO);
}
else
{
lpqos->ProviderSpecific.buf = NULL;
lpqos->ProviderSpecific.len = 0;
dwSize = sizeof(QOS);
}
PrintQos(lpqos);
ret = WSAIoctl(s, SIO_SET_QOS, lpqos, dwSize, NULL, 0,
&dwBytes, NULL, NULL);
if (ret == SOCKET_ERROR)
{
printf("WSAIoctl(SIO_SET_QOS) failed: %d\n",
WSAGetLastError());
return FALSE;
}
return TRUE;
}
//
// Function: Receiver
//
// Description:
//
void DoStuff(SOCKET s)
{
WSANETWORKEVENTS ne;
WSAEVENT hEvent;
SOCKADDR_IN from,
local;
WSABUF wbuf;
DWORD dwBytes,
dwFromLen,
dwFlags;
QOS *lpqos=NULL;
char rcvbuf[DATA_BUFFER_SZ],
sndbuf[DATA_BUFFER_SZ],
qosbuf[QOS_BUFFER_SZ];
int ret;
// No matter when we decide to set QOS, the socket should be
// bound locally (even if its to INADDR_ANY). This is required
// if you're not using WSAConnect which does an implicit bind,
// but we'll do it anyway for simplicity.
//
if (bSender)
{
local.sin_family = AF_INET;
local.sin_port = htons(5150); //0);
local.sin_addr.s_addr = htonl(INADDR_ANY);
}
else
{
local.sin_family = AF_INET;
local.sin_port = htons(5150);
local.sin_addr.s_addr = htonl(INADDR_ANY);
}
if (bind(s, (SOCKADDR *)&local, sizeof(local)) == SOCKET_ERROR)
{
printf("bind() failed: %d\n", WSAGetLastError());
return;
}
// For the receiver there's really only:
// 1. Set QOS beforehand (SET_QOS_BEFORE)
// 2. Set QOS upon an FD_QOS event (SET_QOS_EVENT);
//
if ((!bSender) && (iSetQos != SET_QOS_EVENT))
{
lpqos = &recvQos;
if (SetQosReceivers(s, lpqos) == FALSE)
return;
}
// For the sender you can:
// 1. Set QOS before hand with SIO_SET_QOS (SET_QOS_BEFORE)
// 2. Set QOS during WSAConnect (SET_QOS_DURING)
// 3. Set QOS after WSAConnect (SET_QOSAFTER)
// 4. Set QOS upon FD_QOS (SET_QOS_EVENT)
// (not really meaningful though - no RESV are generated
// by the receiver until it receives a PATH)
//
if ((bSender) && (iSetQos == SET_QOS_BEFORE))
{
// Set QOS before along with QOS_DESTADDR
//
lpqos = &sendQos;
if (SetQosDestAddr(s, lpqos) == FALSE)
return;
}
else if ((bSender) && (iSetQos == SET_QOS_DURING))
{
// Set QOS in WSAConnect call
//
SOCKADDR_IN remote;
lpqos = &sendQos;
remote.sin_family = AF_INET;
remote.sin_port = htons(5150);
remote.sin_addr.s_addr = inet_addr(szReceiverAddr);
printf("WSAConnect() to %s\n", inet_ntoa(remote.sin_addr));
ret = WSAConnect(s, (SOCKADDR *)&remote, sizeof(remote),
NULL, NULL, lpqos, NULL);
if (ret == SOCKET_ERROR)
{
printf("WSAConnect() failed: %d\n", WSAGetLastError());
return;
}
}
else if ((bSender) && (iSetQos == SET_QOS_AFTER))
{
// Call WSAConnect() without any QOS parametrs and then do
// a SIO_SET_QOS. We don't use SetQosDestAddr() as it always
// sets a QOS_DESTADDR object which isn't necessary since
// we've already associated an endpoint address with the
// WSAConnect() call.
//
SOCKADDR_IN remote;
remote.sin_family = AF_INET;
remote.sin_port = htons(5150);
remote.sin_addr.s_addr = inet_addr(szReceiverAddr);
printf("WSAConnect() to %s (NO QOS)\n", inet_ntoa(remote.sin_addr));
ret = WSAConnect(s, (SOCKADDR *)&remote, sizeof(remote),
NULL, NULL, NULL, NULL);
if (ret == SOCKET_ERROR)
{
printf("WSAConnect() failed: %d\n", WSAGetLastError());
return;
}
lpqos = &sendQos;
ret = WSAIoctl(s, SIO_SET_QOS, lpqos, sizeof(QOS), NULL, 0,
&dwBytes, NULL, NULL);
if (ret == SOCKET_ERROR)
{
printf("WSAIoctl(SIO_SET_QOS) failed: %d\n",
WSAGetLastError());
return;
}
}
if (iSetQos == SET_QOS_EVENT)
{
// Just register for FD_QOS events
//
if (bSender)
{
lpqos = &sendQos;
lpqos->SendingFlowspec.ServiceType |= SERVICE_NO_QOS_SIGNALING;
}
else
{
lpqos = &recvQos;
lpqos->ReceivingFlowspec.ServiceType |= SERVICE_NO_QOS_SIGNALING;
}
if (SetQosDestAddr(s, lpqos) == FALSE)
return;
}
hEvent = WSACreateEvent();
if (hEvent == WSA_INVALID_EVENT)
{
printf("WSACreateEvent() failed: %d\n", WSAGetLastError());
return;
}
ret = WSAEventSelect(s, hEvent, FD_READ | FD_WRITE | FD_QOS);
if (ret == SOCKET_ERROR)
{
printf("WSAEventSelect() failed: %d\n", WSAGetLastError());
return;
}
while (1)
{
ret = WSAWaitForMultipleEvents(1, &hEvent, FALSE,
WSA_INFINITE, FALSE);
if (ret == WSA_WAIT_FAILED)
{
printf("WSAWaitForMultipleEvents() failed: %d\n",
WSAGetLastError());
return;
}
ret = WSAEnumNetworkEvents(s, hEvent, &ne);
if (ret == SOCKET_ERROR)
{
printf("WSAEnumNetworkEvents() failed: %d\n",
WSAGetLastError());
return;
}
if (ne.lNetworkEvents & FD_READ)
{
if (ne.iErrorCode[FD_READ_BIT])
{
printf("FD_READ error: %d\n",
ne.iErrorCode[FD_READ_BIT]);
}
else
printf("FD_READ\n");
dwFromLen = sizeof(from);
wbuf.buf = rcvbuf;
wbuf.len = DATA_BUFFER_SZ;
dwFlags = 0;
ret = WSARecvFrom(s, &wbuf, 1, &dwBytes, &dwFlags,
(SOCKADDR *)&from, &dwFromLen, NULL, NULL);
if (ret == SOCKET_ERROR)
{
printf("WSARecvFrom() failed: %d\n",
WSAGetLastError());
return;
}
}
if (ne.lNetworkEvents & FD_WRITE)
{
if (ne.iErrorCode[FD_WRITE_BIT])
{
printf("FD_WRITE error: %d\n",
ne.iErrorCode[FD_WRITE_BIT]);
}
else
printf("FD_WRITE\n");
if ((bSender) && (!bWaitToSend))
{
SOCKADDR_IN receiver;
memset(sndbuf, '$', DATA_BUFFER_SZ);
wbuf.buf = sndbuf;
wbuf.len = DATA_BUFFER_SZ - 1;
receiver.sin_family = AF_INET;
receiver.sin_port = htons(5150);
receiver.sin_addr.s_addr = inet_addr(szReceiverAddr);
ret = WSASendTo(s, &wbuf, 1, &dwBytes, 0,
(SOCKADDR *)&receiver, sizeof(receiver), NULL, NULL);
if (ret == SOCKET_ERROR)
{
if (WSAGetLastError() == WSAEWOULDBLOCK)
continue;
printf("WSASendTo() failed: %d\n",
WSAGetLastError());
return;
}
printf("WSASendTo() wrote: %d bytes to %s\n",
dwBytes, inet_ntoa(receiver.sin_addr));
}
}
if (ne.lNetworkEvents & FD_QOS)
{
if (ne.iErrorCode[FD_QOS_BIT])
{
if (ne.iErrorCode[FD_QOS_BIT] == WSA_QOS_RECEIVERS)
{
printf("WSA_QOS_RECEIVERS\n");
bOkayToSend = TRUE;
}
else
printf("FD_QOS error: %d\n",
ne.iErrorCode[FD_QOS_BIT]);
}
printf("FD_QOS\n");
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(SIO_GET_QOS) failed: %d\n",
WSAGetLastError());
return;
}
PrintQos(lpqos);
//
// See if an RSVP_STATUS_INFO object has been returned
//
if (ChkForQosStatus(lpqos, WSA_QOS_RECEIVERS))
bOkayToSend = TRUE;
if ((bWaitToSend) && (bOkayToSend))
{
SOCKADDR_IN receiver;
memset(sndbuf, '$', DATA_BUFFER_SZ);
wbuf.buf = sndbuf;
wbuf.len = DATA_BUFFER_SZ - 1;
receiver.sin_family = AF_INET;
receiver.sin_port = htons(5150);
receiver.sin_addr.s_addr = inet_addr(szReceiverAddr);
ret = WSASendTo(s, &wbuf, 1, &dwBytes, 0,
(SOCKADDR *)&receiver, sizeof(receiver), NULL, NULL);
if (ret == SOCKET_ERROR)
{
if (WSAGetLastError() == WSAEWOULDBLOCK)
continue;
printf("WSASendTo() failed: %d\n",
WSAGetLastError());
return;
}
printf("WSASendTo() wrote: %d bytes to %s\n",
dwBytes, inet_ntoa(receiver.sin_addr));
}
if (iSetQos == SET_QOS_EVENT)
{
if (bSender)
lpqos->SendingFlowspec.ServiceType =
sendQos.SendingFlowspec.ServiceType;
else
lpqos->ReceivingFlowspec.ServiceType =
recvQos.ReceivingFlowspec.ServiceType;
ret = WSAIoctl(s, SIO_SET_QOS, lpqos, sizeof(QOS),
NULL, 0, &dwBytes, NULL, NULL);
if (ret == SOCKET_ERROR)
{
printf("WSAIoctl(SIO_SET_QOS) failed: %d\n",
WSAGetLastError());
return;
}
iSetQos = SET_QOS_BEFORE;
}
}
}
}
//
// Function: main
//
// Description:
//
int main(int argc, char **argv)
{
WSADATA wsd;
WSAPROTOCOL_INFO *pinfo=NULL;
SOCKET s;
ValidateArgs(argc, argv);
if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)
{
printf("Unable to load Winsock: %d\n", GetLastError());
return -1;
}
pinfo = FindProtocolInfo(AF_INET, SOCK_DGRAM, IPPROTO_UDP,
XP1_QOS_SUPPORTED);
if (!pinfo)
{
printf("unable to find suitable provider!\n");
return -1;
}
printf("Provider returned: %s\n", pinfo->szProtocol);
s = WSASocket(FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO,
FROM_PROTOCOL_INFO, pinfo, 0, WSA_FLAG_OVERLAPPED);
if (s == INVALID_SOCKET)
{
printf("WSASocket() failed: %d\n", WSAGetLastError());
return -1;
}
InitQos();
DoStuff(s);
closesocket(s);
WSACleanup();
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -