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

📄 rnrcs.c

📁 《Windows网络编程技术》附书源码源码. 运行环境:9x/Me/NT/2000/XP/ 源码语言:简体中文 第十章
💻 C
📖 第 1 页 / 共 3 页
字号:
//    service name or specify the wildcard string "*". If an instance
//    is found, send some data to it.
//
void LookupService(GUID *guid, int sapid, int ns, char *servername)
{
    WSAQUERYSET  qs,
                *pqs;
    AFPROTOCOLS  afp[2] = {{AF_IPX,  NSPROTO_IPX},
                           {AF_INET, IPPROTO_UDP}},
                 afpx[1] = {{AF_IPX, NSPROTO_IPX}};
    char         querybuf[sizeof(WSAQUERYSET) + 4096];
    DWORD        nSize = sizeof(WSAQUERYSET) + 4096,
                 i;
    HANDLE       hLookup;
    int          ret, err;

    // Initialize the WSAQUERYSET structure
    //
    pqs = (WSAQUERYSET *)querybuf;    
    memset(&qs, 0, sizeof(WSAQUERYSET));

    qs.dwSize = sizeof(WSAQUERYSET);
    qs.lpszServiceInstanceName = servername;
    qs.lpServiceClassId = guid;
    qs.dwNameSpace = NS_SAP;
    qs.dwNumberOfProtocols = 1; 
    qs.lpafpProtocols = afpx;
    //
    // Begin the lookup. We want the name and address back
    // 
    ret = WSALookupServiceBegin(&qs, LUP_RETURN_ADDR | LUP_RETURN_NAME,
        &hLookup);
    if (ret == SOCKET_ERROR)
    {
        printf("WSALookupServiceBegin failed: %d\n", WSAGetLastError());
        return;
    }
    while (1)
    {
        // Loop, calling WSALookupServiceNext until WSA_E_NO_MORE is
        // returned.
        //
        nSize = sizeof(WSAQUERYSET) + 4096;
        memset(querybuf, 0, nSize);

        pqs->dwSize = sizeof(WSAQUERYSET);
        ret = WSALookupServiceNext(hLookup, 0, &nSize, pqs);
        if (ret == SOCKET_ERROR)
        {
            err = WSAGetLastError();
            if ((err == WSA_E_NO_MORE) || (err == WSAENOMORE))
            {
                printf("No more data found!\n");
                break;
            }
            printf("WSALookupServiceNext() failed: %d\n", WSAGetLastError());
            WSALookupServiceEnd(hLookup);
            return;
        }
        // Now that we've found a server out there, print some info and
        // send some data to it.
        //
        printf("\nFound service: %s\n\n", pqs->lpszServiceInstanceName);
        printf("Returned %d CSADDR structures\n", pqs->dwNumberOfCsAddrs);

        for(i=0; i < pqs->dwNumberOfCsAddrs ;i++)
        {
            switch (pqs->lpcsaBuffer[i].iProtocol)
            {
                case IPPROTO_UDP:
                    printf("IPPROTO_UDP\n");
                    ((SOCKADDR_IN *)pqs->lpcsaBuffer[i].RemoteAddr.lpSockaddr)->sin_family = AF_INET;
                    break;
                case NSPROTO_IPX:
                    printf("NSPROTO_IPX\n");
                    ((SOCKADDR_IPX *)pqs->lpcsaBuffer[i].RemoteAddr.lpSockaddr)->sa_family = AF_IPX;
                    printf("\t[%d] Local  IPX [%s]\n", i,
                        FormatIPXAddr((SOCKADDR_IPX *)(pqs->lpcsaBuffer[i].LocalAddr.lpSockaddr)));
                    printf("\t[%d] Remote IPX [%s]\n", i,
                        FormatIPXAddr((SOCKADDR_IPX *)(pqs->lpcsaBuffer[i].RemoteAddr.lpSockaddr)));
                    break;
                default:
                    printf("Unknown!\n");
                    break;
            }
            // Send data
            //
            ClientSend(pqs->lpcsaBuffer[i].iSocketType, pqs->lpcsaBuffer[i].iProtocol,
                (SOCKADDR *)pqs->lpcsaBuffer[i].RemoteAddr.lpSockaddr, 
                pqs->lpcsaBuffer[i].RemoteAddr.iSockaddrLength, 4);
        }
    }
    WSALookupServiceEnd(hLookup);

    return;
}

//
// Function: ClientSend
//
// Description:
//    Create a socket of the given type and send some data to it
//
BOOL ClientSend(int socktype, int proto, SOCKADDR *server, int len, int count)
{
    WSABUF   wbuf;
    char     sndbuf[MAX_BUFFER_SZ];
    DWORD    dwBytesSent;
    int      i,
             ret;
  
    if (proto == NSPROTO_IPX)
    {
        socks[0] = WSASocket(AF_IPX, socktype, proto, NULL, 0,
            WSA_FLAG_OVERLAPPED);
        if (socks[0] == INVALID_SOCKET)
        {
            printf("WSASocket() failed: %d\n", WSAGetLastError());
            return FALSE;
        }
    }
    else if (proto == IPPROTO_UDP)
    {
        socks[0] = WSASocket(AF_INET, socktype, proto, NULL, 0,
            WSA_FLAG_OVERLAPPED);
        if (socks[0] == INVALID_SOCKET)
        {
            printf("WSASocket() failed: %d\n", WSAGetLastError());
            return FALSE;
        }
    }
    memset(sndbuf, '%', MAX_BUFFER_SZ);
    for(i=0; i < count ;i++)
    {
        wbuf.buf = sndbuf;
        wbuf.len = MAX_BUFFER_SZ -1;

        ret = WSASendTo(socks[0], &wbuf, 1, &dwBytesSent,
            0, server, len , NULL, NULL);
        if (ret == SOCKET_ERROR)
        {
            printf("WSASendTo() failed: %d\n", WSAGetLastError());
            closesocket(socks[0]);
            return FALSE;
        }
    }
    closesocket(socks[0]);

    return TRUE;
}

//
// Function: ServerRecv
//
// Description;
//    Read data pending on the given socket.
//
BOOL ServerRecv(int index)
{
    WSABUF   wbuf;
    char     rcvbuf[MAX_BUFFER_SZ];
    SOCKADDR from;
    DWORD    dwBytesRecv,
             dwFlags,
             dwFromLen;
    int      ret;

    wbuf.buf = rcvbuf;
    dwFlags = 0;
    dwFromLen = sizeof(from);
    wbuf.len = MAX_BUFFER_SZ-1;
        
    ret = WSARecvFrom(socks[index], &wbuf, 1, &dwBytesRecv, &dwFlags,
        &from, &dwFromLen, NULL, NULL);
    if (ret == SOCKET_ERROR)
    {
        if (WSAGetLastError() == WSAEWOULDBLOCK)
            return TRUE;
        else
        {
            printf("WSARecvFrom() failed: %d\n", WSAGetLastError());
            return FALSE;
        }
    }
    rcvbuf[dwBytesRecv] = 0;
    printf("Read: [%s]\n", rcvbuf);

    return TRUE;
}

//
// Function: FormatIPXAddr
//
// Description:
//    Print an IPX address to stdout. We don't use the function
//    WSAAddressToString because it doesn't support IPX.
//
char *FormatIPXAddr(SOCKADDR_IPX *addr)
{
    static char dest[128];
    wsprintf(dest, "%02X%02X%02X%02X.%02X%02X%02X%02X%02X%02X:%04X", 
        (unsigned char)addr->sa_netnum[0],
        (unsigned char)addr->sa_netnum[1],
        (unsigned char)addr->sa_netnum[2],
        (unsigned char)addr->sa_netnum[3],
        (unsigned char)addr->sa_nodenum[0],
        (unsigned char)addr->sa_nodenum[1],
        (unsigned char)addr->sa_nodenum[2],
        (unsigned char)addr->sa_nodenum[3],
        (unsigned char)addr->sa_nodenum[4],
        (unsigned char)addr->sa_nodenum[5],
        ntohs(addr->sa_socket));
    return dest;
}

//
// Function: main
//
// Description:
//    Initialize Winsock, parse the arguments, and start either the
//    client or server depending on the arguments.
//
int main(int argc, char **argv)
{
    WSANAMESPACE_INFO *nsinfo=NULL;
    WSADATA            wsd;
    GUID               svcguid;
    int                nscount, 
                       ret,
                       i;
    WCHAR              szTemp[256];

    ValidateArgs(argc, argv);
    if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)
    {
        printf("WSAStartup() failed: %d\n", GetLastError());
        return -1;
    }
    // Create the GUID that everyone will use, client and server
    //
    SET_NETWARE_SVCID(&svcguid, dwSapId); 

    StringFromGUID2(&svcguid, szTemp, 256);
    printf("GUID: [%S]\n", szTemp);
    //
    // Enumerate the name spaces that we can use
    //
    nsinfo = EnumNameSpaceProviders(&nscount);
    if (!nsinfo)
    {
        printf("unable to enumerate name space info!\n");
        return -1;
    }
    for(i=0; i < nscount ;i++)
        printf("Found NS: %s\n", nsinfo[i].lpszIdentifier);
    
    if (bServer)
    {
        if (szServerName[0] == '*')
        {
            printf("You must specify a server name!\n");
            usage(argv[0]);
            return -1;
        }
        // Install the service class
        //
        if (!InstallServiceClass(&svcguid, nsinfo, nscount))
        {
            printf("Unable to install service class!\n");
            return -1;
        }
        // Advertise our service
        //
        if (!Advertise(&svcguid, nsinfo, nscount, szServerName))
        {
            printf("Unable to advertise service!\n");
            return -1;
        }
        // Register our services for the read event
        //
        for(i=0; i < nscount ;i++)
        {
            ret = WSAEventSelect(socks[i], hEvents[i], FD_READ);
            if (ret == SOCKET_ERROR)
            {
                printf("WSAEventSelect() failed: %d\n", WSAGetLastError());
                return -1;
            }
        }
        while (1)
        {
            // Read any incoming data
            //
            ret = WSAWaitForMultipleEvents(nscount, hEvents, FALSE, 
                INFINITE, TRUE);
            ServerRecv(ret - WSA_WAIT_EVENT_0);
        }
    }
    else
    {
        // Lookup the service
        //
        LookupService(&svcguid, dwSapId, dwNameSpace, szServerName);
    }
    HeapFree(GetProcessHeap(), 0, nsinfo);

    WSACleanup();

    return 0;
}

⌨️ 快捷键说明

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