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

📄 rmcast.cpp

📁 这个是网络编程
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    fec.FECBlockSize              = (USHORT) blocksize;
    fec.FECProActivePackets       = (USHORT) proactive;
    fec.FECGroupSize              = (UCHAR)  blocksize;
    fec.fFECOnDemandParityEnabled = (BOOLEAN)ondemand;

    rc = setsockopt(
            s,
            IPPROTO_RM,
            RM_USE_FEC,
            (char *)&fec,
            sizeof(fec)
            );
    if (rc == SOCKET_ERROR)
    {
        printf("Setting FEC parameters:\n");
        printf("   Block size: %d\n", blocksize);
        printf("   Pro active: %d\n", proactive);
        printf("   Group size: %d\n", groupsize);
        printf("   On demand : %s\n", (ondemand ? "TRUE" : "FALSE"));
    }
    else
    {
        fprintf(stderr, "setsockopt: RM_USE_FEC failed: %d\n", WSAGetLastError());
    }
    return rc;
}

//
// Function: SetWindowSize
//
// Description:
//     This routine sets the window size for the sending socket which includes
//     the byte rate, window size, and window time parameters. Before setting
//     the parameters a simple calculation is performed to determine whether
//     the values passed in make sense. If they don't an error message is 
//     displayed but the set is attempted anyway. If the values don't jive
//     then the option will fail with WSAEINVAL and the default window
//     rate, size, and time are used instead.
//
//
int SetWindowSize(SOCKET s, int windowsize, int windowtime, int windowrate)
{
    RM_SEND_WINDOW  window;
    int             rc;

    memset(&window, 0, sizeof(window));

    if (windowsize != ((windowrate/8) * windowtime))
    {
        printf("Window paramters don't compute!\n");
    }

    window.RateKbitsPerSec = windowrate;
    window.WindowSizeInMSecs = windowtime;
    window.WindowSizeInBytes = windowsize;

    rc = setsockopt(
            s,
            IPPROTO_RM,
            RM_RATE_WINDOW_SIZE,
            (char *)&window,
            sizeof(window)
            );
    if (rc == SOCKET_ERROR)
    {
        fprintf(stderr, "setsockopt: RM_RATE_WINDOW_SIZE failed: %d\n", WSAGetLastError());
    }
    else
    {
        printf("Setting window paramters:\n");
        printf("   Rate (kbits/sec): %d\n", windowrate);
        printf("   Size (bytes)    : %d\n", windowsize);
        printf("   Time (msec)     : %d\n", windowtime);
    }
    return rc;
}

//
// Function: SetLateJoin
//
// Description:
//    This option sets the latejoin value. This specifies the percentage of the
//    window that a receiver can NAK in the event the receiver picked up the 
//    session in the middle of the sender's transmission. This option is set
//    on the sender side and is advertised to the receivers when the session
//    is joined.
//
int SetLateJoin(SOCKET s, int latejoin)
{
    int     rc;

    rc = setsockopt(
            s,
            IPPROTO_RM,
            RM_LATEJOIN,
            (char *)&latejoin,
            sizeof(latejoin)
            );
    if (rc == SOCKET_ERROR)
    {
        fprintf(stderr, "setsockopt: RM_LATEJOIN failed: %d\n", WSAGetLastError());
    }
    else
    {
        printf("Setting latejoin: %d\n", latejoin);
    }
    return rc;
}

//
// Function: main
// 
// Description:
//    Parse the command line arguments, load the Winsock library, 
//    create a socket and join the multicast group. If set as a
//    sender then begin sending messages to the multicast group;
//    otherwise, call recvfrom() to read messages send to the 
//    group.
//    
int _cdecl main(int argc, char **argv)
{
    WSADATA             wsd;
    SOCKET              s,
                        sc;
    SOCKADDR_STORAGE    remote;
    struct addrinfo    *resmulti=NULL,
                       *resif=NULL,
                       *resbind=NULL;
    char               *buf=NULL;
    int                 remotelen,
                        err,
                        rc,
                        i=0;

    // Parse the command line
    ValidateArgs(argc, argv);

    // Load Winsock
    if (WSAStartup(MAKEWORD(1, 1), &wsd) != 0)
    {
        printf("WSAStartup failed\n");
        return -1;
    }

    // Resolve the multicast address
    resmulti = ResolveAddress(gMulticast, gPort, AF_INET, 0, 0);
    if (resmulti == NULL)
    {
        fprintf(stderr, "Unable to convert multicast address '%s': %d\n",
                gMulticast, WSAGetLastError());
        return -1;
    }

    // 
    // Create the socket. In Winsock 1 you don't need any special
    // flags to indicate multicasting.
    //
    s = socket(resmulti->ai_family, gSocketType, gProtocol);
    if (s == INVALID_SOCKET)
    {
        printf("socket failed with: %d\n", WSAGetLastError());
        return -1;
    }
    printf("socket handle = 0x%p\n", s);

    // Allocate the send/receive buffer
    buf = (char *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, gBufferSize);
    if (buf == NULL)
    {
        fprintf(stderr, "HeapAlloc failed: %d\n", GetLastError());
        return -1;
    }

    if (bSender)
    {
        // Bind to the wildcard address
        resbind = ResolveAddress(NULL, gPort, AF_INET, 0, 0);
        if (resbind == NULL)
        {
            fprintf(stderr, "Unable to obtain bind address!\n");
            return -1;
        }

        // Bind the socket
        rc = bind(s, resbind->ai_addr, resbind->ai_addrlen);
        if (rc == SOCKET_ERROR)
        {
            fprintf(stderr, "bind failed: %d\n", WSAGetLastError());
            return -1;
        }
        freeaddrinfo(resbind);

        // If sepcified, set the send interface
        if (gInterfaceCount == 1)
        {
            resif = ResolveAddress(gListenInterface[0], gPort, AF_INET, 0, 0);
            if (resif == NULL)
            {
                return -1;
            }
            rc = SetSendInterface(s, resif);

            freeaddrinfo(resif);

            // Set the TTL to something else. The default TTL is one.
            rc = SetMulticastTtl(s, resmulti->ai_family, gTtl);
            if (rc == SOCKET_ERROR)
            {
                return -1;
            }
        }
        
        // If specified set the late joiner option
        if (gLateJoin != -1)
        {
            SetLateJoin(s, gLateJoin);
        }

        // If specified set the window paramters
        if (bSetSendWindow)
        {
            SetWindowSize(s, gWindowSizeBytes, gWindowSizeMSec, gWindowRateKbitsSec);
        }

        // If specified set the FEC paramters
        if (bUseFec == TRUE)
        {
            SetFecParameters(s, gFecBlockSize, gFecGroupSize, bFecOnDemand, gFecProActive);
        }

        // Connect the socket to the multicast group the session is to be on
        rc = connect(s, resmulti->ai_addr, resmulti->ai_addrlen);
        if (rc == SOCKET_ERROR)
        {
            printf("connect failed: %d\n", WSAGetLastError());
            return -1;
        }

        memset(buf, '^', gBufferSize);

        // Send some data
        for(i=0; i < gCount ; i++)
        {
            rc = send(
                    s, 
                    buf, 
                    gBufferSize,
                    0
                    );
            if (rc == SOCKET_ERROR)
            {
                fprintf(stderr, "send failed with: %d\n", WSAGetLastError());
                return -1;
            }

            printf("SENT %d bytes\n", rc);
        }
    }
    else
    {
        // Bind the socket to the multicast address on which the session will take place
        rc = bind(s, resmulti->ai_addr, resmulti->ai_addrlen);
        if (rc == SOCKET_ERROR)
        {
            fprintf(stderr, "bind failed: %d\n", WSAGetLastError());
            return -1;
        }
        printf("Binding to ");
        PrintAddress(resmulti->ai_addr, resmulti->ai_addrlen);
        printf("\n");

        // Add each supplied interface as a receive interface
        if (gInterfaceCount > 0)
        {
            for(i=0; i < gInterfaceCount ;i++)
            {
                resif = ResolveAddress(gListenInterface[i], "0", AF_INET, 0, 0);
                if (resif == NULL)
                {
                    return -1;
                }
                rc = AddReceiveInterface(s, resif);

                freeaddrinfo(resif);
            }
        }

        // Listen for sessions
        rc = listen(s, 1);
        if (rc == SOCKET_ERROR)
        {
            fprintf(stderr, "listen failed: %d\n", WSAGetLastError());
            return -1;
        }

        // Wait for a session to become available
        remotelen = sizeof(remote);
        sc = accept(s, (SOCKADDR *)&remote, &remotelen);
        if (sc == INVALID_SOCKET)
        {
            fprintf(stderr, "accept failed: %d\n", WSAGetLastError());
            return -1;
        }

        printf("Join multicast session from: ");
        PrintAddress((SOCKADDR *)&remote, remotelen);
        printf("\n");

        while (1)
        {
            // Receive data until an error or until the session is closed
            rc = recv(sc, buf, gBufferSize, 0);
            if (rc == SOCKET_ERROR)
            {
                if ((err = WSAGetLastError()) != WSAEDISCON)
                {
                    fprintf(stderr, "recv failed: %d\n", err);
                }
                break;
            }
            else 
            {
                printf("received %d bytes\n", rc);
            }
        }

        // Close the session socket
        closesocket(sc);
    }

    // Clean up
    freeaddrinfo(resmulti);

    closesocket(s);

    WSACleanup();
    return 0;
}

⌨️ 快捷键说明

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