ID: Q192120
The information in this article applies to:
- Windows NT, version 4.0
- Windows 95
- Windows 98
The Winsock 2 API, WSASocket, allows you to create a socket based on the contents of a passed in WSAPROTOCOL_INFO structure. This readily allows you to create sockets from different installed Winsock 2 Service Providers. You obtain A WSAPROTOCOL_INFO structure by calling the WSAEnumProtocols API and choosing the service provider that you want from the list of WSAPROTOCOL_INFO structures that is returned.
To choose the correct service provider, examine the capabilities supported by each service provider and choose the one that matches your needs. For example, the following code snippet demonstrates how to obtain a service provider that supports TCP/IP and Quality of Service. It is worth noting that the names of Microsoft service providers differ between the various Windows platforms. Therefore, this article should not form the basis of choosing the appropriate service provider.
if (WSAStartup(MAKEWORD(2,2), &WSAData))
printf("WSAStartup %d", WSAGetLastError());
else
{
// First, have WSAEnumProtocols tell you how big a buffer you need.
nRet = WSAEnumProtocols(NULL, lpProtocolBuf, &dwBufLen);
if (SOCKET_ERROR != nRet)
printf("WSAEnumProtocols: should not have succeeded\n");
else if (WSAENOBUFS != (dwErr = WSAGetLastError()))
// WSAEnumProtocols failed for some reason not relating to buffer
// size - also odd.
printf("WSAEnumProtocols(1): %d\n", WSAGetLastError());
else
{
// WSAEnumProtocols failed for the "expected" reason. Therefore,
// you need to allocate a buffer of the appropriate size.
lpProtocolBuf = (WSAPROTOCOL_INFO *)malloc(dwBufLen);
if (lpProtocolBuf)
{
// Now you can call WSAEnumProtocols again with the expectation
// that it will succeed because you have allocated a big enough
// buffer.
nRet = WSAEnumProtocols(NULL, lpProtocolBuf, &dwBufLen);
if (SOCKET_ERROR == nRet)
printf("WSAEnumProtocols(3): %d\n", WSAGetLastError());
else
{
// Loop through protocols, looking for the first service
// provider that meets the matching criteria.
bProtocolFound = FALSE;
for (i=0; i<nRet; i++)
{
if ((IPPROTO_TCP == lpProtocolBuf[i].iProtocol) &&
(XP1_QOS_SUPPORTED == (XP1_QOS_SUPPORTED &
lpProtocolBuf[i].dwServiceFlags1)))
{
bProtocolFound = TRUE;
break;
}
}
}
}
}
}
Once you have chosen a service provider, the following sample code
demonstrates how to actually create a socket using a supplied
WSAPROTOCOL_INFO structure from the service provider you have chosen:
sd = WSASocket(
FROM_PROTOCOL_INFO,
FROM_PROTOCOL_INFO,
FROM_PROTOCOL_INFO,
&lpProtocolBuf[i],
0,
WSA_FLAG_OVERLAPPED);
if (INVALID_SOCKET == sd)
printf("WSASocket %d", WSAGetLastError());
Please note that specifying WSA_FLAG_OVERLAPPED is very useful and is
recommended. For additional information on specifying WSA_FLAG_OVERLAPPED,
please see the following article in the Microsoft Knowledge Base:
ARTICLE-ID: Q179942
TITLE : INFO: WSA_FLAG_OVERLAPPED Is Needed for Non-Blocking Sockets
ARTICLE-ID: Q181610
TITLE : INFO: WSA_FLAG_OVERLAPPED Needed for Timeout on WSASocket
Also, do not forget to free the lpProtocolInfo buffer when you are finished
using it.
Additional query words:
Keywords : kbnetwork kbGQos kbSDKPlatform kbWinsock kbGrpNet
Issue type : kbhowto
Last Reviewed: September 4, 1998