📄 qostcp.c
字号:
printf("WSAIoctl() failed: %d\n",
WSAGetLastError());
return CF_REJECT;
}
}
return CF_ACCEPT;
}
//
// Function: Server
//
// Description:
// This server routine handles incoming client connections.
// First it sets up the listening socket, sets QOS when
// appropriate, and wait for incoming clients and events.
//
void Server(SOCKET s)
{
SOCKET sc[MAX_CONN + 1];
WSAEVENT hAllEvents[MAX_CONN+1];
SOCKADDR_IN local,
client;
int clientsz,
ret,
i;
DWORD dwBytesRet;
WSANETWORKEVENTS ne;
// Initialize the arrays to invalid values
//
for(i = 0; i < MAX_CONN+1; i++)
{
hAllEvents[i] = WSA_INVALID_EVENT;
sc[i] = INVALID_SOCKET;
}
// Array index 0 will be our listening socket
//
hAllEvents[0] = WSACreateEvent();
sc[0] = s;
nConns = 0;
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;
}
listen(s, 7);
if (iSetQos == SET_QOS_BEFORE)
{
ret = WSAIoctl(sc[0], SIO_SET_QOS, &serverQos,
sizeof(serverQos), NULL, 0, &dwBytesRet, NULL, NULL);
if (ret == SOCKET_ERROR)
{
printf("WSAIoctl(SIO_SET_QOS) failed: %d\n",
WSAGetLastError());
return;
}
printf("Set QOS on listening socket:\n");
PrintQos(&serverQos);
}
if (WSAEventSelect(sc[0], hAllEvents[0], FD_ACCEPT) ==
SOCKET_ERROR)
{
printf("WSAEventSelect() failed: %d\n", WSAGetLastError());
return;
}
while (1)
{
ret = WSAWaitForMultipleEvents(nConns+1, hAllEvents, FALSE,
WSA_INFINITE, FALSE);
if (ret == WSA_WAIT_FAILED)
{
printf("WSAWaitForMultipleObject() failed: %d\n",
WSAGetLastError());
return;
}
if ((i = ret - WSA_WAIT_EVENT_0) > 0) // Client network event
HandleClientEvents(sc, hAllEvents, i);
else
{
ret = WSAEnumNetworkEvents(sc[0], hAllEvents[0],
&ne);
if (ret == SOCKET_ERROR)
{
printf("WSAEnumNetworkevents() failed: %d\n",
WSAGetLastError());
return;
}
if ((ne.lNetworkEvents & FD_ACCEPT) == FD_ACCEPT)
{
if (ne.iErrorCode[FD_ACCEPT_BIT])
printf("FD_ACCEPT error: %d\n",
ne.iErrorCode[FD_ACCEPT_BIT]);
else
printf("FD_ACCEPT\n");
clientsz = sizeof(client);
sc[++nConns] = WSAAccept(s, (SOCKADDR *)&client,
&clientsz, SrvCondAccept, sc[nConns]);
if (sc[nConns] == SOCKET_ERROR)
{
printf("WSAAccept() failed: %d\n",
WSAGetLastError());
nConns--;
return;
}
hAllEvents[nConns] = WSACreateEvent();
Sleep(10000);
if (iSetQos == SET_QOS_AFTER)
{
ret = WSAIoctl(sc[nConns], SIO_SET_QOS,
&serverQos, sizeof(serverQos), NULL, 0,
&dwBytesRet, NULL, NULL);
if (ret == SOCKET_ERROR)
{
printf("WSAIoctl() failed: %d\n",
WSAGetLastError());
return;
}
}
ret = WSAEventSelect(sc[nConns],
hAllEvents[nConns], FD_READ | FD_WRITE |
FD_CLOSE | FD_QOS);
if (ret == SOCKET_ERROR)
{
printf("WSAEventSelect() failed: %d\n",
WSAGetLastError());
return;
}
}
if (ne.lNetworkEvents & FD_CLOSE)
printf("FD_CLOSEn");
if (ne.lNetworkEvents & FD_READ)
printf("FD_READn");
if (ne.lNetworkEvents & FD_WRITE)
printf("FD_WRITEn");
if (ne.lNetworkEvents & FD_QOS)
printf("FD_QOS\n");
}
}
return;
}
//
// Function: Client
//
// Description:
// The client routine initiates the connection, sets QOS when
// appropriate, and handle incoming events.
//
void Client(SOCKET s)
{
SOCKADDR_IN server,
local;
WSABUF wbuf;
DWORD dwBytes,
dwBytesSent,
dwBytesRecv,
dwFlags;
HANDLE hEvent;
int ret, i;
char databuf[DATA_BUFFER_SZ];
QOS *lpqos;
WSANETWORKEVENTS ne;
hEvent = WSACreateEvent();
if (hEvent == NULL)
{
printf("WSACreateEvent() failed: %d\n", WSAGetLastError());
return;
}
lpqos = NULL;
if (iSetQos == SET_QOS_BEFORE)
{
local.sin_family = AF_INET;
local.sin_port = htons(0);
local.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(s, (SOCKADDR *)&local, sizeof(local)) ==
SOCKET_ERROR)
{
printf("bind() failed: %d\n", WSAGetLastError());
return;
}
ret = WSAIoctl(s, SIO_SET_QOS, &clientQos,
sizeof(clientQos), NULL, 0, &dwBytes, NULL, NULL);
if (ret == SOCKET_ERROR)
{
printf("WSAIoclt(SIO_SET_QOS) failed: %d\n",
WSAGetLastError());
return;
}
}
else if (iSetQos == SET_QOS_DURING)
lpqos = &clientQos;
else if (iSetQos == SET_QOS_EVENT)
{
clientQos.SendingFlowspec.ServiceType |=
SERVICE_NO_QOS_SIGNALING;
clientQos.ReceivingFlowspec.ServiceType |=
SERVICE_NO_QOS_SIGNALING;
ret = WSAIoctl(s, SIO_SET_QOS, &clientQos,
sizeof(clientQos), NULL, 0, &dwBytes, NULL, NULL);
if (ret == SOCKET_ERROR)
{
printf("WSAIoctl() failed: %d\n", WSAGetLastError());
return;
}
}
server.sin_family = AF_INET;
server.sin_port = htons(5150);
server.sin_addr.s_addr = inet_addr(szServerAddr);
printf("Connecting to: %s\n", inet_ntoa(server.sin_addr));
ret = WSAConnect(s, (SOCKADDR *)&server, sizeof(server),
NULL, NULL, lpqos, NULL);
if (ret == SOCKET_ERROR)
{
printf("WSAConnect() failed: %d\n", WSAGetLastError());
return;
}
ret = WSAEventSelect(s, hEvent, FD_READ | FD_WRITE |
FD_CLOSE | FD_QOS);
if (ret == SOCKET_ERROR)
{
printf("WSAEventSelect() failed: %d\n", WSAGetLastError());
return;
}
wbuf.buf = databuf;
wbuf.len = DATA_BUFFER_SZ;
memset(databuf, '#', DATA_BUFFER_SZ);
databuf[DATA_BUFFER_SZ-1] = 0;
while (1)
{
ret = WSAWaitForMultipleEvents(1, &hEvent, FALSE,
WSA_INFINITE, FALSE);
if (ret == WSA_WAIT_FAILED)
{
printf("WSAWaitForMulipleEvents() 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");
wbuf.len = 4096;
dwFlags = 0;
ret = WSARecv(s, &wbuf, 1, &dwBytesRecv, &dwFlags,
NULL, NULL);
if (ret == SOCKET_ERROR)
{
printf("WSARecv() failed: %d\n",
WSAGetLastError());
return;
}
printf("Read: %d bytes\n", dwBytesRecv);
wbuf.len = dwBytesRecv;
ret = WSASend(s, &wbuf, 1, &dwBytesSent, 0, NULL,
NULL);
if (ret == SOCKET_ERROR)
{
printf("WSASend() failed: %d\n",
WSAGetLastError());
return;
}
printf("Sent: %d bytes\n", dwBytesSent);
}
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 (!bWaitToSend)
{
wbuf.buf = databuf;
wbuf.len = DATA_BUFFER_SZ;
//
// If the network can't support the bandwidth
// don't send
//
if (!AbleToSend(s))
{
printf("Network is unable to provide "
"sufficient best effort bandwidth\n");
printf("before the reservation "
"request is approved\n");
}
for(i = 0; i < 1; i++)
{
ret = WSASend(s, &wbuf, 1, &dwBytesSent, 0,
NULL, NULL);
if (ret == SOCKET_ERROR)
{
printf("WSASend() failed: %d\n",
WSAGetLastError());
return;
}
printf("Sent: %d bytes\n", dwBytesSent);
}
}
}
if (ne.lNetworkEvents & FD_CLOSE)
{
if (ne.iErrorCode[FD_CLOSE_BIT])
printf("FD_CLOSE error: %d\n",
ne.iErrorCode[FD_CLOSE_BIT]);
else
printf("FD_CLOSE ...\n");
closesocket(s);
WSACloseEvent(hEvent);
return;
}
if (ne.lNetworkEvents & FD_QOS)
{
char buf[QOS_BUFFER_SZ];
QOS *lpqos = NULL;
DWORD dwBytes;
BOOL bRecvRESV = FALSE;
if (ne.iErrorCode[FD_QOS_BIT])
{
printf("FD_QOS error: %d\n",
ne.iErrorCode[FD_QOS_BIT]);
if (ne.iErrorCode[FD_QOS_BIT] == WSA_QOS_RECEIVERS)
bRecvRESV = TRUE;
}
else
printf("FD_QOS\n");
lpqos = (QOS *)buf;
ret = WSAIoctl(s, SIO_GET_QOS, NULL, 0,
buf, QOS_BUFFER_SZ, &dwBytes, NULL, NULL);
if (ret == SOCKET_ERROR)
{
printf("WSAIoctl(SIO_GET_QOS) failed: %d\n",
WSAGetLastError());
return;
}
PrintQos(lpqos);
//
// Check to see if there is a status object returned
// in the QOS structure which may also contain the
// WSA_QOS_RECEIVERS flag
//
if (ChkForQosStatus(lpqos, WSA_QOS_RECEIVERS))
bRecvRESV = TRUE;
if (iSetQos == SET_QOS_EVENT)
{
lpqos->SendingFlowspec.ServiceType =
clientQos.SendingFlowspec.ServiceType;
ret = WSAIoctl(s, SIO_SET_QOS, lpqos, dwBytes,
NULL, 0, &dwBytes, NULL, NULL);
if (ret == SOCKET_ERROR)
{
printf("WSAIoctl(SIO_SET_QOS) failed: %d\n",
WSAGetLastError());
return;
}
//
// Change iSetQos so we don't set QOS again if we
// receive another FD_QOS event
//
iSetQos = SET_QOS_BEFORE;
}
if (bWaitToSend && bRecvRESV)
{
wbuf.buf = databuf;
wbuf.len = DATA_BUFFER_SZ;
for(i = 0; i < 1; i++)
{
ret = WSASend(s, &wbuf, 1, &dwBytesSent, 0,
NULL, NULL);
if (ret == SOCKET_ERROR)
{
printf("WSASend() failed: %d\n",
WSAGetLastError());
return;
}
printf("Sent: %d bytes\n", dwBytesSent);
}
}
}
}
return;
}
//
// Function: main
//
// Description:
// Initialize Winsock, parse command line arguments, create
// a QOS TCP socket, and call the appropriate handler
// routine depending on the arguments supplied
//
int main(int argc, char **argv)
{
WSADATA wsd;
WSAPROTOCOL_INFO *pinfo = NULL;
SOCKET s;
// Parse the command line
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_STREAM, IPPROTO_TCP,
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();
if (bServer)
Server(s);
else
Client(s);
closesocket(s);
WSACleanup();
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -