Strange GQOS Problem
Hi.
I have a very strange QOS related problem.
My problem is that ic cannot get the sending client application to concurently mark two or more sockets with higher priority DiffServ code.
I have included the source files for both the server and the client test applications.
Server is: IoSrv.h& IoSrv.cpp
Client is IoClnt.h& IoClnt.cpp and also the QOSSocket files, since i've tried almost all the available IO mechanisms.
Any help will be greatly appreciated, since I'm really out of options and ideeas.
I must mention that if i precreate the FLOW definitions, using tcmon.exe, and
then bind the sockets on the predefined ports(in my case 777 and 778),
everything works as expected.
I just can't get GQOS to set up the second or more FLOW for me.
Even sStranger, should the first socket close, the one for which the GQOS managed
to setup a TC flow and to correctly tag data, the next one starts
working properly, FLOW created and all.
It feels like there is a system wide restriction, and I say sytem because
I used to different processes to no avail, so that GQOS is able to setup
and monitor only one TC FLOW at one time.
I must add that I'm using XP and Win2003, and I'm not really interested in
reverting back to win 2000 for this.
Thank you in advance for any ideas and sugestions.
Mihnea Craciun
// IoSrv.h
#pragma
once#include
"resource.h"// IoSrv.cpp : Defines the entry point for the console application.
//
#include
"stdafx.h"#include
"IoSrv.h"#include
"mswsock.h"#include
"Ws2tcpip.h"#ifdef
_DEBUG#define
new DEBUG_NEW#endif
LPWSAPROTOCOL_INFO g_pProtocol = NULL;
// The one and only application object
CWinApp theApp;
class
IOOVER :public WSAOVERLAPPED{
public
:IOOVER(SLIST_ENTRY * pEntr)
{
::ZeroMemory(
reinterpret_cast(const_cast(this)),sizeof(IOOVER));dwBufferSize = 2048;
pBuffer =
new CHAR[dwBufferSize];pEntry = pEntr;
bSetQOS = FALSE;
}
~IOOVER()
{
if (pBuffer){
pBuffer = (
delete pBuffer,NULL);}
}
typedefenum {Send,Rcvd} IOType;BOOL bSetQOS;
CHAR *pBuffer;
DWORD dwBufferSize;
IOType eType;
SOCKET sActive;
SOCKET sListen;
SLIST_ENTRY *pEntry;
};
class
ACCEPTOV :public WSAOVERLAPPED{
public
:ACCEPTOV()
{
::ZeroMemory(
reinterpret_cast(const_cast(this)),sizeof(ACCEPTOV));dwLocalAddressLength =
sizeof(sockaddr_in) + 16;dwRemoteAddressLength =
sizeof(sockaddr_in) + 16;lpOutputBuffer =
new BYTE[(sizeof(sockaddr_in) + 16) * 2];::ZeroMemory(lpOutputBuffer,(
sizeof(sockaddr_in) + 16) * 2);pLocalSockaddr = (SOCKADDR *)
new BYTE[dwLocalAddressLength];pRemoteSockaddr = (SOCKADDR *)
new BYTE[dwRemoteAddressLength];}
~ACCEPTOV()
{
if (lpOutputBuffer)lpOutputBuffer = (
delete lpOutputBuffer,NULL);if (pLocalSockaddr)pLocalSockaddr = (
delete pLocalSockaddr,NULL);if (pRemoteSockaddr)pRemoteSockaddr = (
delete pRemoteSockaddr,NULL);}
SOCKET sListen;
SOCKET sNew;
PVOID lpOutputBuffer;
DWORD dwReceiveDataLength;
DWORD dwLocalAddressLength;
DWORD dwRemoteAddressLength;
SOCKADDR* pLocalSockaddr;
INT LocalSockaddrLength;
SOCKADDR* pRemoteSockaddr;
INT RemoteSockaddrLength;
};
class
SOCKET_ENTRY{
public
:SOCKET_ENTRY()
{
::ZeroMemory(
reinterpret_cast(const_cast(this)),sizeof(SOCKET_ENTRY));}
SLIST_ENTRY sEntry;
SOCKET sSocket;
};
class
IOOVERENTRY{
public
:IOOVERENTRY()
{
::ZeroMemory(
reinterpret_cast(const_cast(this)),sizeof(IOOVERENTRY));}
~IOOVERENTRY()
{
if (pOV)pOV = (
delete pOV,NULL);}
SLIST_ENTRY sEntry;
IOOVER *pOV;
};
using
namespace std;int
Main(SHORT sPort);VOID CALLBACK AcceptCompletion(DWORD dwErrorCode,DWORD dwNumberOfBytesTransfered,LPOVERLAPPED lpOverlapped);
VOID CALLBACK IOCompletion (DWORD dwErrorCode,DWORD dwNumberOfBytesTransfered,LPOVERLAPPED lpOverlapped);
BOOL SetQOS(SOCKET Sock);
int
CALLBACK ConditionalAccept(LPWSABUF lpCallerId,LPWSABUF lpCallerData,LPQOS lpSQOS,LPQOS lpGQOS,LPWSABUF lpCalleeId,LPWSABUF lpCalleeData,GROUP FAR * g,DWORD_PTR dwCallbackData);//Globals
SOCKET sMainSock = NULL;
//LPFN_ACCEPTEX lpfnAcceptEx = NULL;
SLIST_HEADER ClientSocketListHead;
SLIST_HEADER FREEIOOVERListHead;
LONG bClosing = 0;
DWORD WINAPI SelectThread(LPVOID lpThreadParameter)
{
fd_set fd;
FD_ZERO(&fd);
FD_SET(sMainSock,&fd);
TIMEVAL stime = {0,100*1000};
do{
FD_ZERO(&fd);
FD_SET(sMainSock,&fd);
int ret = select(NULL,&fd,NULL,NULL,&stime);if (ret > 0){
ACCEPTOV *pOV =
new ACCEPTOV;pOV->sListen = sMainSock;
pOV->sNew = accept(sMainSock,pOV->pRemoteSockaddr,(
int*)&(pOV->dwRemoteAddressLength));SetQOS(pOV->sNew);
AcceptCompletion(NULL,NULL,pOV);
}
elseif (ret == SOCKET_ERROR)break;}
while (!InterlockedCompareExchange(&bClosing,TRUE,TRUE));return 0;}
BOOL SetQOS(SOCKET Sock)
{
QOS sQOS;
//SendingFlowspecsQOS.SendingFlowspec.DelayVariation = QOS_NOT_SPECIFIED;
sQOS.SendingFlowspec.Latency = QOS_NOT_SPECIFIED;
sQOS.SendingFlowspec.MaxSduSize = QOS_NOT_SPECIFIED;
sQOS.SendingFlowspec.MinimumPolicedSize = QOS_NOT_SPECIFIED;
sQOS.SendingFlowspec.PeakBandwidth = QOS_NOT_SPECIFIED;
sQOS.SendingFlowspec.ServiceType = QOS_NOT_SPECIFIED;
sQOS.SendingFlowspec.TokenBucketSize = QOS_NOT_SPECIFIED;
sQOS.SendingFlowspec.TokenRate = QOS_NOT_SPECIFIED;
//ReceivingFlowspecsQOS.ReceivingFlowspec.DelayVariation = QOS_NOT_SPECIFIED;
sQOS.ReceivingFlowspec.Latency = QOS_NOT_SPECIFIED;
sQOS.ReceivingFlowspec.MaxSduSize = QOS_NOT_SPECIFIED;
sQOS.ReceivingFlowspec.MinimumPolicedSize = QOS_NOT_SPECIFIED;
sQOS.ReceivingFlowspec.PeakBandwidth = QOS_NOT_SPECIFIED;
sQOS.ReceivingFlowspec.ServiceType = QOS_NOT_SPECIFIED;
sQOS.ReceivingFlowspec.TokenBucketSize = QOS_NOT_SPECIFIED;
sQOS.ReceivingFlowspec.TokenRate = QOS_NOT_SPECIFIED;
//ProviderSpecificsQOS.ProviderSpecific.buf = NULL;
sQOS.ProviderSpecific.len = 0;
sQOS.SendingFlowspec.TokenRate = 10240;
sQOS.SendingFlowspec.ServiceType = SERVICETYPE_GUARANTEED | SERVICE_NO_QOS_SIGNALING;
sQOS.ReceivingFlowspec.TokenRate = 10240;
sQOS.ReceivingFlowspec.ServiceType = SERVICETYPE_BESTEFFORT | SERVICE_NO_QOS_SIGNALING ;
QOS_OBJECT_HDR hdr = {QOS_OBJECT_END_OF_LIST,
sizeof(QOS_OBJECT_HDR)};sQOS.ProviderSpecific.len =
sizeof(QOS_OBJECT_HDR);sQOS.ProviderSpecific.buf = (
char *)&hdr;DWORD nBytesRcvd = 0;
if (WSAIoctl(Sock,SIO_SET_QOS,&sQOS,sizeof(QOS),NULL,NULL,&nBytesRcvd,NULL,NULL) == SOCKET_ERROR){
DWORD dwErr = WSAGetLastError();
return FALSE;}
return TRUE;}
int
CALLBACK ConditionalAccept(LPWSABUF lpCallerId,LPWSABUF lpCallerData,LPQOS lpSQOS,LPQOS lpGQOS,LPWSABUF lpCalleeId,LPWSABUF lpCalleeData,GROUP * g,DWORD_PTR dwCallbackData){
return CF_ACCEPT;}
int
_tmain(int argc, TCHAR* argv[], TCHAR* envp[]){
int nRetCode = 0;// initialize MFC and print and error on failureif (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0)){
// TODO: change error code to suit your needs_tprintf(_T(
"Fatal Error: MFC initialization failed\n"));nRetCode = 1;
}
else{
return Main(1800);}
return nRetCode;}
int
Main(SHORT sPort){
WORD wVersionRequested;
WSADATA wsaData;
int err;wVersionRequested = MAKEWORD( 2, 2 );
InitializeSListHead(&ClientSocketListHead);
InitializeSListHead(&FREEIOOVERListHead);
IOOVERENTRY *pEntry;
for (int i = 0; i < 64; i++){
pEntry =
new IOOVERENTRY;pEntry->pOV =
new IOOVER(&pEntry->sEntry);InterlockedPushEntrySList(&FREEIOOVERListHead,&pEntry->sEntry);
}
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ){
return 1;}
if ( LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2 ){
WSACleanup( );
return 1;}
DWORD dwBuffSize = NULL;
int nProtocol = IPPROTO_TCP;int nProt = WSAEnumProtocols(&nProtocol,NULL,&dwBuffSize);LPWSAPROTOCOL_INFO pProtocols = (LPWSAPROTOCOL_INFO)
new BYTE[dwBuffSize];nProt = WSAEnumProtocols(&nProtocol,pProtocols,&dwBuffSize);
for (int i = 0; i < nProt; i++){
if (pProtocols[i].dwServiceFlags1 & XP1_QOS_SUPPORTED){
g_pProtocol =
new WSAPROTOCOL_INFO;memcpy_s(g_pProtocol,
sizeof(WSAPROTOCOL_INFO),&(pProtocols[i]),sizeof(WSAPROTOCOL_INFO));}
}
if (pProtocols)delete pProtocols;if (!g_pProtocol){
return 1;}
sMainSock = WSASocket(AF_INET,SOCK_STREAM,IPPROTO_TCP,
/*NULL*/g_pProtocol,0,WSA_FLAG_OVERLAPPED);sockaddr_in saServer;
hostent* localHost;
char* localIP;localHost = gethostbyname(
"");localIP = inet_ntoa (*(
struct in_addr *)*localHost->h_addr_list);saServer.sin_family = AF_INET;
saServer.sin_addr.s_addr = inet_addr(localIP);
saServer.sin_port = htons(sPort);
if (bind( sMainSock,(SOCKADDR*) &saServer,sizeof(saServer)) == SOCKET_ERROR){
closesocket(sMainSock);
return WSACleanup();}
if (listen(sMainSock,SOMAXCONN) == SOCKET_ERROR){
closesocket(sMainSock);
return WSACleanup();}
CreateThread(NULL,NULL,&SelectThread,NULL,NULL,NULL);
int i = getchar();InterlockedIncrement(&bClosing);
closesocket(sMainSock);
SOCKET_ENTRY *pSockEntry = NULL;
do{
pSockEntry =
reinterpret_cast(InterlockedPopEntrySList(&ClientSocketListHead));if (pSockEntry){
closesocket(pSockEntry->sSocket);
delete pSockEntry;}
}
while(pSockEntry);while (SleepEx(100,TRUE) == WAIT_IO_COMPLETION){};IOOVERENTRY *pIoEntry = NULL;
do{
pIoEntry =
reinterpret_cast(InterlockedPopEntrySList(&FREEIOOVERListHead));if (pIoEntry){
delete pIoEntry;}
}
while(pIoEntry);if (g_pProtocol)g_pProtocol = (
delete g_pProtocol,NULL);return WSACleanup();}
VOID CALLBACK IOCompletion (DWORD dwErrorCode,DWORD dwNumberOfBytesTransfered,LPOVERLAPPED lpOverlapped)
{
IOOVER *pOV =
reinterpret_cast(lpOverlapped);//Sleep(5);CString strTrace;
if (dwNumberOfBytesTransfered == 0){
InterlockedPushEntrySList(&FREEIOOVERListHead,pOV->pEntry);
closesocket(pOV->sActive);
return;}
switch(pOV->eType){
case IOOVER::Rcvd:{
IOOVERENTRY *pEntry = NULL;
do{
pEntry =
reinterpret_cast(InterlockedPopEntrySList(&FREEIOOVERListHead));if (pEntry == NULL){
IOOVERENTRY *pNewEntry =
new IOOVERENTRY;pNewEntry->pOV =
new IOOVER(&pNewEntry->sEntry);InterlockedPushEntrySList(&FREEIOOVERListHead,&pNewEntry->sEntry);
}
}
while(pEntry == NULL);DWORD dwBytes = NULL,dwFlags = NULL;
WSABUF wsa;
wsa.buf = pEntry->pOV->pBuffer;
wsa.len = pEntry->pOV->dwBufferSize;
pEntry->pOV->sActive = pOV->sActive;
pEntry->pOV->sListen = pOV->sListen;
pEntry->pOV->eType = IOOVER::Rcvd;
WSARecv(pEntry->pOV->sActive,&wsa,1,&dwBytes,&dwFlags,pEntry->pOV,NULL);
wsa.buf = pOV->pBuffer;
wsa.len = dwNumberOfBytesTransfered;
pOV->eType = IOOVER::Send;
WSASend(pOV->sActive,&wsa,1,&dwBytes,dwFlags,pOV,NULL);
break;}
case IOOVER::Send:{
InterlockedPushEntrySList(&FREEIOOVERListHead,pOV->pEntry);
}
break;}
}
VOID CALLBACK AcceptCompletion(DWORD dwErrorCode,DWORD dwNumberOfBytesTransfered,LPOVERLAPPED lpOverlapped)
{
ACCEPTOV *pOv =
reinterpret_cast(lpOverlapped);if (InterlockedCompareExchange(&bClosing,1,1) == 1){
delete pOv;return;}
DWORD dwBytes = NULL;
BindIoCompletionCallback((HANDLE)pOv->sNew,&IOCompletion,NULL);
IOOVERENTRY *pEntry = NULL;
do{
pEntry =
reinterpret_cast(InterlockedPopEntrySList(&FREEIOOVERListHead));if (pEntry == NULL){
IOOVERENTRY *pNewEntry =
new IOOVERENTRY;pNewEntry->pOV =
new IOOVER(&pNewEntry->sEntry);InterlockedPushEntrySList(&FREEIOOVERListHead,&pNewEntry->sEntry);
}
}
while(pEntry == NULL);BOOL bOption = TRUE;
int nResult = setsockopt(pOv->sNew, IPPROTO_TCP, TCP_NODELAY, (LPCSTR)&bOption,sizeof(BOOL));ATLASSERT(nResult == 0);
int nOption = 0;nResult = setsockopt(pOv->sNew, SOL_SOCKET, SO_SNDBUF, (LPCSTR)&nOption,
sizeof(int));ATLASSERT(nResult == 0);
DWORD dwFlags = 0;
WSABUF wsa;
wsa.buf = pEntry->pOV->pBuffer;
wsa.len = pEntry->pOV->dwBufferSize;
pEntry->pOV->sActive = pOv->sNew;
pEntry->pOV->sListen = pOv->sListen;
pEntry->pOV->eType = IOOVER::Rcvd;
pEntry->pOV->bSetQOS = TRUE;
WSARecv(pEntry->pOV->sActive,&wsa,1,&dwBytes,&dwFlags,pEntry->pOV,NULL);
SOCKET_ENTRY *pSocketEntry =
new SOCKET_ENTRY;pSocketEntry->sSocket = pEntry->pOV->sActive;
InterlockedPushEntrySList(&ClientSocketListHead,&pSocketEntry->sEntry);
delete pOv;}
//IoClnt.h
#pragma
once#include
"resource.h"// IoClnt.cpp : Defines the entry point for the console application.
//
#include
"stdafx.h"#include
"IoClnt.h"#include
#include
#include
#include
"QOSSocket.h"#ifdef
_DEBUG#define
new DEBUG_NEW#endif
#define
THREAD_NUMBER 1#define
NUM_SOCKS 2// The one and only application object
CWinApp theApp;
using
namespace std;int
Main (CString strHost,CString strPort);int
MainAsync (CString strHost,CString strPort);int
MainSelect (CString strHost,CString strPort);int
MainCompletion (CString strHost,CString strPort);typedef
struct _TC_SETUP{
QOS_TRAFFIC_CLASS qosTrafficClass;
QOS_DS_CLASS qosDSClass;
QOS_OBJECT_HDR qosEndOfList;
}TC_SETUP,*PTC_SETUP;
struct
OVEX:public OVERLAPPED{
OVEX()
{
SecureZeroMemory(
this,sizeof(OVEX));Buff.len = 1460;
Buff.buf =
newchar[Buff.len];}
~OVEX()
{
if (Buff.buf){
Buff.buf = (
delete Buff.buf,NULL);Buff.len = 0;
}
}
BYTE nType;
SOCKET sSock;
WSABUF Buff;
};
OVEX* arrOutOv[NUM_SOCKS] = {0};
OVEX* arrInOv[NUM_SOCKS] = {0};
QOS sQOS;
int
_tmain(int argc, TCHAR* argv[], TCHAR* envp[]){
int nRetCode = 0;// initialize MFC and print and error on failureif (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0)){
// TODO: change error code to suit your needs_tprintf(_T(
"Fatal Error: MFC initialization failed\n"));nRetCode = 1;
}
else{
//SendingFlowspecsQOS.SendingFlowspec.DelayVariation = QOS_NOT_SPECIFIED;
sQOS.SendingFlowspec.Latency = QOS_NOT_SPECIFIED;
sQOS.SendingFlowspec.MaxSduSize = QOS_NOT_SPECIFIED;
sQOS.SendingFlowspec.MinimumPolicedSize = QOS_NOT_SPECIFIED;
sQOS.SendingFlowspec.PeakBandwidth = QOS_NOT_SPECIFIED;
sQOS.SendingFlowspec.ServiceType = QOS_NOT_SPECIFIED;
sQOS.SendingFlowspec.TokenBucketSize = QOS_NOT_SPECIFIED;
sQOS.SendingFlowspec.TokenRate = QOS_NOT_SPECIFIED;
//ReceivingFlowspecsQOS.ReceivingFlowspec.DelayVariation = QOS_NOT_SPECIFIED;
sQOS.ReceivingFlowspec.Latency = QOS_NOT_SPECIFIED;
sQOS.ReceivingFlowspec.MaxSduSize = QOS_NOT_SPECIFIED;
sQOS.ReceivingFlowspec.MinimumPolicedSize = QOS_NOT_SPECIFIED;
sQOS.ReceivingFlowspec.PeakBandwidth = QOS_NOT_SPECIFIED;
sQOS.ReceivingFlowspec.ServiceType = QOS_NOT_SPECIFIED;
sQOS.ReceivingFlowspec.TokenBucketSize = QOS_NOT_SPECIFIED;
sQOS.ReceivingFlowspec.TokenRate = QOS_NOT_SPECIFIED;
//ProviderSpecificsQOS.ProviderSpecific.buf = NULL;
sQOS.ProviderSpecific.len = 0;
sQOS.SendingFlowspec.TokenRate = 16000;
sQOS.SendingFlowspec.ServiceType = SERVICETYPE_GUARANTEED | SERVICE_NO_QOS_SIGNALING;
sQOS.ReceivingFlowspec.ServiceType = SERVICETYPE_BESTEFFORT | SERVICE_NO_QOS_SIGNALING;
QOS_OBJECT_HDR hdr = {QOS_OBJECT_END_OF_LIST,
sizeof(QOS_OBJECT_HDR)};sQOS.ProviderSpecific.len =
sizeof(QOS_OBJECT_HDR);sQOS.ProviderSpecific.buf = (
char *)&hdr;//return Main(_T("192.168.200.32"),_T("1800"));//return MainAsync(_T("192.168.200.32"),_T("1800"));//return MainSelect(_T("192.168.200.32"),_T("1800"));return MainCompletion(_T("192.168.200.15"),_T("1800"));}
return nRetCode;}
int
Main (CString strHost,CString strPort){
WSADATA WSAData;
WSAStartup(MAKEWORD(2,2), &WSAData);
DWORD dwBuffSize = NULL;
int nProtocol = IPPROTO_TCP;int nProt = WSAEnumProtocols(&nProtocol,NULL,&dwBuffSize);LPWSAPROTOCOL_INFO pProtocols = (LPWSAPROTOCOL_INFO)
new BYTE[dwBuffSize];LPWSAPROTOCOL_INFO pProtocol = NULL;
nProt = WSAEnumProtocols(&nProtocol,pProtocols,&dwBuffSize);
for (int i = 0; i < nProt; i++){
if (pProtocols[i].dwServiceFlags1 & XP1_QOS_SUPPORTED){
pProtocol =
new WSAPROTOCOL_INFO;memcpy_s(pProtocol,
sizeof(WSAPROTOCOL_INFO),&(pProtocols[i]),sizeof(WSAPROTOCOL_INFO));}
}
if (pProtocols)delete pProtocols;if (!pProtocol){
return 1;}
srand(GetTickCount());
for (int i = 0; i < 1; i++){
SOCKET sClnt = WSASocket(AF_INET,SOCK_STREAM,IPPROTO_TCP,pProtocol,NULL,WSA_FLAG_OVERLAPPED);
if (sClnt == INVALID_SOCKET)return 1;sockaddr_in saServer;
hostent* localHost;
char* localIP;localHost = gethostbyname(
"");localIP = inet_ntoa (*(
struct in_addr *)*localHost->h_addr_list);saServer.sin_family = AF_INET;
saServer.sin_addr.s_addr = inet_addr(localIP);
int nRes = ERROR_SUCCESS;SHORT sPort = 0;
retry:
do{
sPort = rand();
}
while ((htons(sPort) > 1024) && (htons(sPort) < USHRT_MAX));saServer.sin_port = htons(sPort);
nRes = bind( sClnt,(SOCKADDR*) &saServer,
sizeof(saServer));if (nRes == SOCKET_ERROR){
DWORD dwErr = WSAGetLastError();
if (dwErr = WSAEADDRINUSE)goto retry;closesocket(sClnt);
return WSACleanup();}
DWORD nBytesRcvd = 0;
if (WSAIoctl(sClnt,SIO_SET_QOS,&sQOS,sizeof(QOS),NULL,NULL,&nBytesRcvd,NULL,NULL) == SOCKET_ERROR){
DWORD dwErr = WSAGetLastError();
return 1;}
addrinfo aiHints = {0};
addrinfo *aiList = NULL;
aiHints.ai_family = AF_INET;
aiHints.ai_socktype = SOCK_STREAM;
aiHints.ai_protocol = IPPROTO_TCP;
if (getaddrinfo(CStringA(strHost),CStringA(strPort),&aiHints,&aiList) != 0)return 1;addrinfo *aiListCursor = aiList;
BOOL bConected = FALSE;
while (aiListCursor){
if (connect(sClnt,aiListCursor->ai_addr,(int)aiListCursor->ai_addrlen) != 0){
aiListCursor = aiListCursor->ai_next;
continue;}
else{
freeaddrinfo(aiList);
aiList = NULL;
bConected = TRUE;
break;}
}
if (!bConected)return 1;BYTE outBuff[1460] = {0};
BYTE innBuff[1460] = {0};
srand(GetTickCount());
for (int i = 0; i <sizeof(outBuff) / 2; i++)((SHORT*)outBuff)[i] = SHORT(rand());
BOOL bContinue = TRUE;
int i = 0;while (bContinue){
bContinue &= (send(sClnt,(
constchar *)outBuff,sizeof(outBuff),NULL) != SOCKET_ERROR);bContinue &= (recv(sClnt,(
char *)innBuff,sizeof(innBuff),NULL) != SOCKET_ERROR);i++;
/*if (i > 99)bContinue = FALSE;*/
}
shutdown(sClnt,SD_BOTH);
closesocket(sClnt);
}
delete pProtocol;WSACleanup();
return 0;}
int
MainAsync (CString strHost,CString strPort){
WSADATA WSAData;
WSAStartup(MAKEWORD(2,2), &WSAData);
DWORD dwBuffSize = NULL;
int nProtocol = IPPROTO_TCP;int nProt = WSAEnumProtocols(&nProtocol,NULL,&dwBuffSize);LPWSAPROTOCOL_INFO pProtocols = (LPWSAPROTOCOL_INFO)
new BYTE[dwBuffSize];LPWSAPROTOCOL_INFO pProtocol = NULL;
nProt = WSAEnumProtocols(&nProtocol,pProtocols,&dwBuffSize);
for (int i = 0; i < nProt; i++){
if (pProtocols[i].dwServiceFlags1 & XP1_QOS_SUPPORTED){
pProtocol =
new WSAPROTOCOL_INFO;memcpy_s(pProtocol,
sizeof(WSAPROTOCOL_INFO),&(pProtocols[i]),sizeof(WSAPROTOCOL_INFO));}
}
if (pProtocols)delete pProtocols;if (!pProtocol){
return 1;}
SOCKET sClnt[NUM_SOCKS];
CQOSSocket* sAsyncClnt =
new CQOSSocket[NUM_SOCKS];for (int i = 0; i <sizeof(sClnt)/sizeof(SOCKET);i++){
/*SOCKET*/sClnt[i] = WSASocket(AF_INET,SOCK_STREAM,IPPROTO_TCP,pProtocol,NULL,WSA_FLAG_OVERLAPPED);
if (sClnt[i] == INVALID_SOCKET)return 1;DWORD nBytesRcvd = 0;
if (WSAIoctl(sClnt[i],SIO_SET_QOS,&sQOS,sizeof(QOS),NULL,NULL,&nBytesRcvd,NULL,NULL) == SOCKET_ERROR){
DWORD dwErr = WSAGetLastError();
return 1;}
if (!sAsyncClnt[i].Attach(sClnt[i]))return 1;sAsyncClnt[i].Connect(strHost,1800);
}
delete pProtocol;AFX_MODULE_THREAD_STATE *pState = AfxGetModuleThreadState();
MSG msg;
while (GetMessage(&msg,NULL,NULL,NULL)){
if (msg.hwnd == pState->m_hSocketWindow){
SOCKET sSocket = (SOCKET)msg.wParam;
if (WSAGETSELECTEVENT(msg.lParam) == FD_QOS){
CString strMsg; strMsg.Format(_T(
"FD_QOS Recvd on Socket: %d\n"),sSocket);cout << strMsg << endl;
}
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
delete[] sAsyncClnt;return 1;}
int
MainSelect (CString strHost,CString strPort){
WSADATA WSAData;
WSAStartup(MAKEWORD(2,2), &WSAData);
DWORD dwBuffSize = NULL;
int nProtocol = IPPROTO_TCP;int nProt = WSAEnumProtocols(&nProtocol,NULL,&dwBuffSize);LPWSAPROTOCOL_INFO pProtocols = (LPWSAPROTOCOL_INFO)
new BYTE[dwBuffSize];LPWSAPROTOCOL_INFO pProtocol = NULL;
nProt = WSAEnumProtocols(&nProtocol,pProtocols,&dwBuffSize);
for (int i = 0; i < nProt; i++){
if (pProtocols[i].dwServiceFlags1 & XP1_QOS_SUPPORTED){
pProtocol =
new WSAPROTOCOL_INFO;memcpy_s(pProtocol,
sizeof(WSAPROTOCOL_INFO),&(pProtocols[i]),sizeof(WSAPROTOCOL_INFO));}
}
if (pProtocols)delete pProtocols;if (!pProtocol){
return 1;}
SOCKET sClnt[NUM_SOCKS];
for (int i = 0; i <sizeof(sClnt)/sizeof(SOCKET);i++){
sClnt[i] = WSASocket(AF_INET,SOCK_STREAM,IPPROTO_TCP,pProtocol,NULL,WSA_FLAG_OVERLAPPED);
if (sClnt[i] == INVALID_SOCKET)return 1;/*DWORD nBytesRcvd = 0;if (WSAIoctl(sClnt[i],SIO_SET_QOS,&sQOS,sizeof(QOS),NULL,NULL,&nBytesRcvd,NULL,NULL) == SOCKET_ERROR)
{
DWORD dwErr = WSAGetLastError();
return 1;
}*/
addrinfo aiHints = {0};
addrinfo *aiList = NULL;
aiHints.ai_family = AF_INET;
aiHints.ai_socktype = SOCK_STREAM;
aiHints.ai_protocol = IPPROTO_TCP;
if (getaddrinfo(CStringA(strHost),CStringA(strPort),&aiHints,&aiList) != 0)return 1;addrinfo *aiListCursor = aiList;
BOOL bConected = FALSE;
while (aiListCursor){
if (WSAConnect(sClnt[i],aiListCursor->ai_addr,(int)aiListCursor->ai_addrlen,NULL,NULL,&sQOS,NULL) != 0){
aiListCursor = aiListCursor->ai_next;
continue;}
else{
freeaddrinfo(aiList);
aiList = NULL;
bConected = TRUE;
break;}
}
if (!bConected)return 1;}
delete pProtocol;BYTE outBuff[1460] = {0};
BYTE innBuff[1460] = {0};
srand(GetTickCount());
for (int i = 0; i <sizeof(outBuff) / 2; i++)((SHORT*)outBuff)[i] = SHORT(rand());
for (int i = 0; i < NUM_SOCKS; i++)send(sClnt[i],(
constchar *)outBuff,sizeof(outBuff),NULL);fd_set fdread,fdwrite,fdexcept;
do{
FD_ZERO(&fdread);
FD_ZERO(&fdwrite);
FD_ZERO(&fdexcept);
for (int i = 0; i < NUM_SOCKS; i++){
FD_SET(sClnt[i],&fdread);
FD_SET(sClnt[i],&fdwrite);
FD_SET(sClnt[i],&fdexcept);
}
select(NUM_SOCKS,&fdread,&fdwrite,&fdexcept,NULL);
if (fdread.fd_count){
for (u_int i = 0; i < fdread.fd_count;i++){
recv(fdread.fd_array[i],(
char *)innBuff,sizeof(innBuff),NULL);send(fdread.fd_array[i],(
char *)innBuff,sizeof(innBuff),NULL);}
}
if (fdwrite.fd_count){
for (u_int i = 0; i < fdread.fd_count;i++)send(fdwrite.fd_array[i],(
constchar *)outBuff,sizeof(outBuff),NULL);}
if (fdexcept.fd_count)ASSERT(FALSE);
}
while(TRUE);return 1;}
int
MainCompletion (CString strHost,CString strPort){
WSADATA WSAData;
WSAStartup(MAKEWORD(2,2), &WSAData);
DWORD dwBuffSize = NULL;
int nProtocol = IPPROTO_TCP;int nProt = WSAEnumProtocols(&nProtocol,NULL,&dwBuffSize);LPWSAPROTOCOL_INFO pProtocols = (LPWSAPROTOCOL_INFO)
new BYTE[dwBuffSize];LPWSAPROTOCOL_INFO pProtocol = NULL;
nProt = WSAEnumProtocols(&nProtocol,pProtocols,&dwBuffSize);
for (int i = 0; i < nProt; i++){
if (pProtocols[i].dwServiceFlags1 & XP1_QOS_SUPPORTED){
pProtocol =
new WSAPROTOCOL_INFO;memcpy_s(pProtocol,
sizeof(WSAPROTOCOL_INFO),&(pProtocols[i]),sizeof(WSAPROTOCOL_INFO));}
}
if (pProtocols)delete pProtocols;if (!pProtocol){
return 1;}
static HANDLE hIOCompletion = NULL;SOCKET sClnt[NUM_SOCKS];
USHORT sPort[NUM_SOCKS] = {777,778};
for (int i = 0; i <sizeof(sClnt)/sizeof(SOCKET);i++){
sClnt[i] = WSASocket(AF_INET,SOCK_STREAM,IPPROTO_TCP,pProtocol,NULL,WSA_FLAG_OVERLAPPED);
if (sClnt[i] == INVALID_SOCKET)return 1;arrOutOv[i] =
new OVEX;arrInOv[i] =
new OVEX;arrInOv[i]->nType = 1;
//ReadarrOutOv[i]->nType = 2;
//WritearrInOv[i]->sSock = arrOutOv[i]->sSock = sClnt[i];
//set socketULONG bEnable = TRUE;
sockaddr_in saServer;
hostent* localHost;
char* localIP;localHost = gethostbyname(
"");localIP = inet_ntoa (*(
struct in_addr *)*localHost->h_addr_list);saServer.sin_family = AF_INET;
saServer.sin_addr.s_addr = inet_addr(localIP);
int nRes = ERROR_SUCCESS;// SHORT sPort = 0;
//retry: do
// {
// sPort = rand();
// } while ((htons(sPort) > 1024) && (htons(sPort) < USHRT_MAX));
saServer.sin_port = htons(sPort[i]);
nRes = bind( sClnt[i],(SOCKADDR*) &saServer,
sizeof(saServer));if (nRes == SOCKET_ERROR){
DWORD dwErr = WSAGetLastError();
/*if (dwErr = WSAEADDRINUSE)goto retry;*/
closesocket(sClnt[i]);
return WSACleanup();}
addrinfo aiHints = {0};
addrinfo *aiList = NULL;
aiHints.ai_family = AF_INET;
aiHints.ai_socktype = SOCK_STREAM;
aiHints.ai_protocol = IPPROTO_TCP;
if (getaddrinfo(CStringA(strHost),CStringA(strPort),&aiHints,&aiList) != 0)return 1;addrinfo *aiListCursor = aiList;
BOOL bConected = FALSE;
while (aiListCursor){
if (WSAConnect(sClnt[i],aiListCursor->ai_addr,(int)aiListCursor->ai_addrlen,NULL,NULL,&sQOS,NULL) != 0){
aiListCursor = aiListCursor->ai_next;
continue;}
else{
freeaddrinfo(aiList);
aiList = NULL;
bConected = TRUE;
break;}
}
if (!bConected)return 1;DWORD nBytesRcvd = 0;
if (WSAIoctl(sClnt[i],FIONBIO,&bEnable,sizeof(ULONG),NULL,NULL,&nBytesRcvd,NULL,NULL) == SOCKET_ERROR){
DWORD dwErr = WSAGetLastError();
return 1;}
hIOCompletion = CreateIoCompletionPort((HANDLE)sClnt[i],hIOCompletion,i,0);
ASSERT(hIOCompletion != NULL);
}
delete pProtocol;srand(GetTickCount());
for (int i = 0; i < NUM_SOCKS; i++){
for (u_long t = 0; t < arrOutOv[i]->Buff.len/ 2; t++)((SHORT*)arrOutOv[i]->Buff.buf)[t] = SHORT(rand());
DWORD dwRecvd = 0,dwFlags = NULL;
int nRes = WSARecv(sClnt[i],&(arrInOv[i]->Buff),1,&dwRecvd,&dwFlags,arrInOv[i],NULL);if (nRes == NULL && dwRecvd > 0)ASSERT(FALSE);
if (nRes == SOCKET_ERROR){
DWORD dwErr = WSAGetLastError();
if (dwErr != WSA_IO_PENDING)ASSERT(FALSE);
}
do{
nRes = WSASend(sClnt[i],&(arrOutOv[i]->Buff),1,&dwRecvd,NULL,arrOutOv[i],NULL);
}
while((nRes == NULL && dwRecvd > 0));if (nRes == SOCKET_ERROR){
DWORD dwErr = WSAGetLastError();
if (dwErr != WSA_IO_PENDING)ASSERT(FALSE);
}
}
DWORD dwBytes = 0;
ULONG nKey;
OVEX *pOvex = NULL;
BOOL bRet = FALSE;
while (TRUE){
bRet = GetQueuedCompletionStatus(hIOCompletion,&dwBytes,&nKey,
reinterpret_cast(&pOvex),INFINITE);if (bRet){
if (pOvex == NULL)ASSERT(FALSE);
else{
if (dwBytes == NULL)continue;switch (pOvex->nType){
case 1://Read{
DWORD dwRecvd = 0,dwFlags = 0;
int nRes = 0;do{
nRes = WSARecv(sClnt[nKey],&(arrInOv[nKey]->Buff),1,&dwRecvd,&dwFlags,arrInOv[nKey],NULL);
}
while(nRes == NULL && dwRecvd > 0);if (nRes == SOCKET_ERROR){
DWORD dwErr = WSAGetLastError();
if (dwErr != WSA_IO_PENDING)ASSERT(FALSE);
}
break;}
case 2://Write{
DWORD dwSent = 0,dwFlags = 0;
int nRes = 0;do{
nRes = WSASend(sClnt[nKey],&(arrOutOv[nKey]->Buff),1,&dwSent,NULL,arrOutOv[nKey],NULL);
}
while((nRes == NULL && dwSent > 0));if (nRes == SOCKET_ERROR){
DWORD dwErr = WSAGetLastError();
if (dwErr != WSA_IO_PENDING)ASSERT(FALSE);
}
break;}
default:ASSERT(FALSE);
}
}
}
else{
DWORD dwErr = WSAGetLastError();
ASSERT(FALSE);
}
}
return 1;}
#pragma
once// CQOSSocket command target
class
CQOSSocket :public CAsyncSocket{
public
:CQOSSocket();
virtual ~CQOSSocket();staticvoid PASCAL DoCallBack(WPARAM wParam, LPARAM lParam){
return CAsyncSocket::DoCallBack(wParam,lParam);}
protected
:virtualvoid OnReceive(int nErrorCode);virtualvoid OnSend(int nErrorCode);virtualvoid OnOutOfBandData(int nErrorCode);virtualvoid OnAccept(int nErrorCode);virtualvoid OnConnect(int nErrorCode);virtualvoid OnClose(int nErrorCode);private
:BYTE m_outBuff[1460];
BYTE m_innBuff[1460];
};
// QOSSocket.cpp : implementation file
//
#include
"stdafx.h"#include
"IoClnt.h"#include
"QOSSocket.h"// CQOSSocket
CQOSSocket::CQOSSocket()
{
srand(GetTickCount());
for (int i = 0; i <sizeof(m_outBuff) / 2; i++)((SHORT*)m_outBuff)[i] = SHORT(rand());
}
CQOSSocket::~CQOSSocket()
{
}
// CQOSSocket member functions
void
CQOSSocket::OnReceive(int nErrorCode){
//ATLTRACE(_T("%S On Sock: 0x%08x Error: %d\n"),__FUNCTION__,m_hSocket,nErrorCode);if (nErrorCode == 0){
Receive(m_innBuff,
sizeof(m_innBuff),NULL);Send(m_outBuff,
sizeof(m_outBuff),NULL);}
elseASSERT(FALSE);
}
void
CQOSSocket::OnSend(int nErrorCode){
//ATLTRACE(_T("%S On Sock: 0x%08x Error: %d\n"),__FUNCTION__,m_hSocket,nErrorCode);if (nErrorCode == 0)Send(m_outBuff,
sizeof(m_outBuff),NULL);elseASSERT(FALSE);
}
void
CQOSSocket::OnOutOfBandData(int nErrorCode){
//ATLTRACE(_T("%S On Sock: 0x%08x Error: %d\n"),__FUNCTION__,m_hSocket,nErrorCode);}
void
CQOSSocket::OnAccept(int nErrorCode){
//ATLTRACE(_T("%S On Sock: 0x%08x Error: %d\n"),__FUNCTION__,m_hSocket,nErrorCode);}
void
CQOSSocket::OnConnect(int nErrorCode){
//ATLTRACE(_T("%S On Sock: 0x%08x Error: %d\n"),__FUNCTION__,m_hSocket,nErrorCode);if (nErrorCode == 0){
Send(m_outBuff,
sizeof(m_outBuff),NULL);Receive(m_innBuff,
sizeof(m_innBuff),NULL);}
elseASSERT(FALSE);
}
void
CQOSSocket::OnClose(int nErrorCode){
//ATLTRACE(_T("%S On Sock: 0x%08x Error: %d\n"),__FUNCTION__,m_hSocket,nErrorCode);}

