⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rnrcs.cpp

📁 这个是网络编程
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// Module: rnrcs.cpp
//
// Description:
//    This sample illustrates how a server can create a socket and
//    advertise the existance of the service to clients.  It also
//    shows how a client with knowledge of the server's name only
//    can find out how to connect to the server in order to transmit
//    data. The server accomplishes this by installing a service
//    class which describes the basic characteristics of the service
//    and then registering an instance of the server which references
//    the given class. The service can be registered for multiple
//    name spaces such as IPX and NTDS.
//
//    The client can query the available name spaces for knowledge
//    of a service of the given name. If the query completes 
//    successfully, the address of the service is returned.  All
//    the client needs to do is use that address in either a
//    connect or sendto call.
//
// Compile:
//     cl rnrcs.cpp ws2_32.lib user32.lib ole32.lib
//
// Command Line Arguments/Parameters
//     rnrcs -c ServiceName -s ServiceName -t ID -n NameSpace
//       -c ServiceName      Act as client and query for this service name
//       -s ServiceName      Act as server and register service as this name
//       -t ID               SAP ID to register under
//       -n NameSpace        Name space to register service under
//                             Supported namespaces are NS_ALL, NS_SAP, NS_NTDS
//
#include <winsock2.h>
#include <windows.h>

#include <ws2tcpip.h>
#include <svcguid.h>
#include <wsipx.h>
#include <wsnwlink.h> 
#include <nspapi.h>

#include <stdio.h>
#include <stdlib.h>

#define MAX_NUM_CSADDRS        20
#define MAX_INTERFACE_LIST     20
#define MAX_NUM_SOCKETS        20

#define MAX_BUFFER_SZ         512

#define MAX_SERVER_NAME_SZ     64

#define DEFAULT_SERVER_NAME    "JunkServer"

char    szServerName[MAX_SERVER_NAME_SZ];   // Server name
BOOL    bServer;                            // Client or server?
DWORD   dwNameSpace,                        // Name space to register on
        dwSapId;                            // Used to create a GUID
SOCKET  socks[MAX_NUM_SOCKETS];             // Socket handles for our server
HANDLE  hEvents[MAX_NUM_SOCKETS];

BOOL  ClientSend(int socktype, int proto, SOCKADDR *server, 
         int len, int count);
char *FormatIPXAddr(SOCKADDR_IPX *addr);

//
// Function: usage
//
// Description:
//    Print usage information.
//
void usage(char *progname)
{
    printf("usage: %s  -c Service -s  -t ID -n [NS_ALL|NS_NTDS|NS_SAP]\n",
        progname);
    printf("  -c ServiceName      Act as client and query for this service name\n");
    printf("  -s ServiceName      Act as server and register service as this name\n");
    printf("  -t ID               SAP ID to register under\n");
    printf("                        This is arbitrary...just needed to create a GUID\n");
    printf("  -n NameSpace        Name space to register service under\n");
    printf("                        Can be one of the strings: NS_ALL, NS_NTDS, or NS_SAP\n");
    ExitProcess(-1);
}

//
// Function: ValidateArgs
//
// Description:
//    Parse command line parameters and set some global variables used
//    by the application.
//
void ValidateArgs(int argc, char **argv)
{
    int    i;

    // Set some default values
    //
    strcpy(szServerName, DEFAULT_SERVER_NAME);
    dwNameSpace = NS_ALL;
    dwSapId = 200;

    for(i=0; i < MAX_NUM_SOCKETS ;i++)
        socks[i] = SOCKET_ERROR;

    if (argc > 1)
    {
        for (i = 1; i < argc; i++)
        {
            if ( (argv[i][0] == '-') || (argv[i][0] == '/')  )
            {
                switch (tolower(argv[i][1]) )
                {
                    case 't':        // SAP id used to generate GUID
                        if (i+1 < argc)
                        {
                            dwSapId = atoi(argv[i+1]);
                            ++i;
                        }

                        break;
                    case 'c':        // Client, query for given service
                        bServer = FALSE;

                        if (i+1 < argc)
                        {
                            strcpy(szServerName, argv[i+1]);
                            ++i;
                        }

                        break;
                    case 's':        // Server, register as the given service
                        bServer = TRUE;

                        if (i+1 < argc)
                        {
                            strcpy(szServerName, argv[i+1]);
                            ++i;
                        }
                        break;
                    case 'n':        // Name spaces to register service under

                        if (i+1 < argc)
                        {
                            if(strlen(argv[i+1]) >= 3)
                            {
                                if (0 == _stricmp(argv[i+1],"NS_NTDS"))
                                {
                                    dwNameSpace = NS_NTDS;
                                }
                                else if (0 == _stricmp(argv[i+1],"NS_SAP"))
                                {
                                    dwNameSpace = NS_SAP;
                                }
                            }
                            ++i;
                        }
                        break;

                    default:
                        usage(argv[0]);
                        return;
                }
            }
            else
                usage(argv[0]);

        }
    }

    return;
}

//
// Function: EnumNameSpaceProviders
//
// Description:
//    Returns an array of those name spaces which our application
//    supports. If one day, NS_DNS becomes dynamic, modify this
//    function to return that structure as well. 
//
WSANAMESPACE_INFO *EnumNameSpaceProviders(int *count)
{
    WSANAMESPACE_INFO *nsinfo,
                      *nsinfocpy;
    BYTE              *pbuf=NULL,
                      *pbufcpy=NULL;
    DWORD              dwBytes;
    int                i, j,
                       ret;

    *count = 0;
    dwBytes = 0;
    //
    // First find out how big of a buffer we need
    //
    ret = WSAEnumNameSpaceProviders(&dwBytes, NULL);
    if (ret == SOCKET_ERROR)
    {
        if (WSAGetLastError() != WSAEFAULT)
        {
            printf("WSAEnumNameSpaceProviders() failed: %d\n",
                WSAGetLastError());
            return NULL;
        }
    }
    // Allocate this buffer and call the function again
    //
    pbuf = (BYTE *)GlobalAlloc(GPTR, dwBytes);
    if (!pbuf)
    {
        printf("GlobaAlloc() failed: %d\n", GetLastError());
        return NULL;
    }
    nsinfo = (WSANAMESPACE_INFO *)pbuf;
    ret = WSAEnumNameSpaceProviders(&dwBytes, nsinfo);
    if (ret == SOCKET_ERROR)
    {
        printf("WSAEnumNameSpaceProviders() failed: %d\n",
            WSAGetLastError());
        HeapFree(GetProcessHeap(), 0, pbuf);
        return NULL;
    }
    // Make a copy buffer which we will return our data in
    //
    pbufcpy = (BYTE *) GlobalAlloc(GPTR, dwBytes);
    if (!pbufcpy)
    {
        printf("GlobaAlloc() failed: %d\n", GetLastError());
        return NULL;
    }
    // Loop throug the returned name space structures picking
    // those which our app supports
    //
    nsinfocpy = (WSANAMESPACE_INFO *)pbufcpy;
    printf("%d name spaces are available\n", ret);

    j = 0;
    for(i=0; i < ret ;i++)
    {
        switch (nsinfo[i].dwNameSpace)
        {
            // Currently we only support SAP or NTDS name spaces
            // so ignore anything else (like DNS)
            //
            case NS_SAP:
            case NS_NTDS: 
                memcpy(&nsinfocpy[j++], &nsinfo[i], sizeof(WSANAMESPACE_INFO));
                break;
        }
    }
    // Free the original buffer and return our copy of useable name spaces
    //
    GlobalFree(pbuf);

    printf("Found %d useable name spaces\n", j);

    *count = j;
    return nsinfocpy;
}

//
// Function: InstallServiceClass
//
// Description:
//    This function installs the service class which is required before
//    registering an instance of a service. A service class defines the
//    generic attributes of a class of services such as whether it is
//    connection oriented or not as well as what protocols is supports
//    (IPX, IP, etc).
//
BOOL InstallServiceClass(GUID *svcguid, WSANAMESPACE_INFO *nsinfo, int nscount)
{
    WSASERVICECLASSINFO  sci;
    WSANSCLASSINFO      *nsclass=NULL;
    DWORD                dwZero=0,
                         dwUdpPort=0;
    char                 szServiceClassName[64];
    int                  i,
                         ret;

    // Generate a name of our service class
    //
    wsprintf(szServiceClassName, "ServiceClass: %003d", dwSapId);
    printf("Installing service class: '%s'\n", szServiceClassName);
    //
    // There are 2 attributes we need to set for every name space
    // we want to register in: Connection Oriented/Connectionless as
    // well as the address family of the protocols we support.
    //
    nsclass = (WSANSCLASSINFO *) GlobalAlloc(GPTR, sizeof(WSANSCLASSINFO) * nscount * 2);
    if (!nsclass)
    {
        printf("GlobalAlloc() failed: %d\n", GetLastError());
        return FALSE;
    }
    // Initialize the structure
    //
    memset(&sci, 0, sizeof(sci));
    sci.lpServiceClassId = svcguid;
    sci.lpszServiceClassName = szServiceClassName;
    sci.dwCount = nscount * 2;
    sci.lpClassInfos = nsclass;

    for(i=0; i < nscount ;i++)
    {
        // No matter what name space we use we set the connection
        // oriented attribute to false (i.e. connectionless)
        //
        nsclass[i*2].lpszName = SERVICE_TYPE_VALUE_CONN;
        nsclass[i*2].dwNameSpace = nsinfo[i].dwNameSpace;
        nsclass[i*2].dwValueType = REG_DWORD;
        nsclass[i*2].dwValueSize = sizeof(DWORD);
        nsclass[i*2].lpValue = &dwZero;

        if (nsinfo[i].dwNameSpace == NS_NTDS)
        {
            // If NS_NTDS is available we will be running a UDP
            // based service on the given port number
            //
            printf("Setting NS_NTDS info...\n");
            nsclass[(i*2)+1].lpszName = SERVICE_TYPE_VALUE_UDPPORT;
            nsclass[(i*2)+1].dwNameSpace = nsinfo[i].dwNameSpace;
            nsclass[(i*2)+1].dwValueType = REG_DWORD;
            nsclass[(i*2)+1].dwValueSize = sizeof(DWORD);
            nsclass[(i*2)+1].lpValue = &dwUdpPort;            

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -