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

📄 rmcast.cpp

📁 < WINDOWS网络编程>>英文版,一本详细讲解WINDOWS平台下网络编程的国外经典书籍,适合英文水平高的牛人
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// Sample: Reliable multicasting sample
//
// File:
//      rmcast.cpp      - this file
//      resolve.cpp     - common name resolution routines
//      resolve.h       - header file for common name resolution routines
//
// Purpose:
//    This sample illustrates the reliable multicast protocol. The client is
//    simple, create a reliable multicast socket, set the receive interfaces,
//    and wait for a session. After the session is joined, receive data on the
//    accepted session. For the server, the window size and other opttions may
//    be specified on the command line.
//
// Compile:
//    cl -o rmcast rmcast.c resolve.cpp ws2_32.lib
//
// Command Line Options/Parameters
//    rmcast.exe
//       -fb int   FEC block size
//       -fg int   FEC group size
//       -fo       Enable on-demand FEC
//       -fp int   Set FEC pro-active count
//       -i        Local interface
//                    Sender: This specifies the send interface
//                    Receiver: This is the listen interface - may be specified multiple times
//       -j  int   Late join percentage (sender only)
//       -m  str   Dotted decimal multicast IP addres to join
//       -n  int   Number of messages to send/receive
//       -p  int   Port number to use
//       -s        Act as server (send data); otherwise receive data.
//       -t  int   Set multicast TTL
//       -wb int   Set the send window size in bytes
//       -wr int   Set the send window rate in bytes/second
//       -ws int   Set the send window size in seconds
//       -z  int   Size of the send/recv buffer
//
#include <winsock2.h>
#include <ws2tcpip.h>
#include <wsrm.h>
#include <windows.h>

#include "resolve.h"

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

#define MCASTADDRV4    "234.5.6.7"
#define MCASTPORT      "25000"
#define BUFSIZE        1024
#define DEFAULT_COUNT  500
#define DEFAULT_TTL    8

#define MAX_LOCAL_INTERFACES    64

BOOL  bSender=FALSE,            // Act as sender?
      bUseFec=FALSE,            // Enable FEC
      bFecOnDemand=FALSE,       // Enable FEC on demand
      bSetSendWindow=FALSE;
int   gSocketType=SOCK_RDM,     // Reliable datagram
      gProtocol=IPPROTO_RM,     // Reliable multicast protocol
      gCount=DEFAULT_COUNT,     // Number of messages to send/receive
      gTtl=DEFAULT_TTL,         // Multicast TTL value
      gBufferSize=BUFSIZE;      // Buffer size for send/recv
int   gInterfaceCount=0;        // Number of local interfaces specified
char *gListenInterface[MAX_LOCAL_INTERFACES], // Set of listening interfaces
     *gMulticast=MCASTADDRV4,   // Multicast group to join
     *gPort=MCASTPORT;          // Port number to use

// Window size paramters
int   gWindowRateKbitsSec=0,
      gWindowSizeBytes=0,
      gWindowSizeMSec=0;

// FEC parameters
int   gFecBlockSize=8,
      gFecGroupSize=16,
      gFecProActive=8;

// Late join option
int   gLateJoin=-1;

//
// Function: usage
//
// Description:
//    Print usage information and exit.
//
void usage(char *progname)
{
    printf("usage: %s -s -m str -p int -i str -l -n int\n",
        progname);
    printf(" -fb int   FEC block size\n");
    printf(" -fg int   FEC group size\n");
    printf(" -fo       Enable on-demand FEC\n");
    printf(" -fp int   Set FEC pro-active count\n");
    printf(" -i        Local interface\n");
    printf("              Sender: This specifies the send interface\n");
    printf("              Receiver: This is the listen interface - may be specified multiple times\n");
    printf(" -j  int   Late join percentage (sender only)\n");
    printf(" -m  str   Dotted decimal multicast IP addres to join\n");
    printf(" -n  int   Number of messages to send/receive\n");
    printf(" -p  int   Port number to use\n");
    printf("              The default port is: %s\n", MCASTPORT);
    printf(" -s        Act as server (send data); otherwise\n");
    printf("              receive data.\n");
    printf(" -t  int   Set multicast TTL\n");
    printf(" -wb int   Set the send window size in bytes\n");
    printf(" -wr int   Set the send window rate in bytes/second\n");
    printf(" -ws int   Set the send window size in seconds\n");
    printf(" -z  int   Size of the send/recv buffer\n");
    ExitProcess(-1);
}

//
// Function: ValidateArgs
//
// Description
//    Parse the command line arguments and set some global flags
//    depeding on the values.
//
void ValidateArgs(int argc, char **argv)
{
    int      i, rc;

    for(i=1; i < argc ;i++)
    {
        if ((argv[i][0] == '-') || (argv[i][0] == '/'))
        {
            switch (tolower(argv[i][1]))
            {
                case 'f':        // Use fec
                    if (strlen(argv[i]) != 3)
                        usage(argv[0]);
                    bUseFec = TRUE;
                    switch (tolower(argv[i][2]))
                    {
                        case 'b':       // FEC block size
                            if (i+1 >= argc)
                                usage(argv[0]);
                            gFecBlockSize = atol(argv[++i]);
                            break;
                        case 'g':       // FEC group size
                            if (i+1 >= argc)
                                usage(argv[0]);
                            gFecGroupSize = atol(argv[++i]);
                            break;
                        case 'o':       // FEC on demand
                            bFecOnDemand = TRUE;
                            break;
                        case 'p':       // Pro active FEC count
                            if (i+1 >= argc)
                                usage(argv[0]);
                            gFecProActive = atol(argv[++i]);
                            break;
                        default:
                            usage(argv[0]);
                            break;
                    }
                    break;
                case 'i':        // local interface to use
                    if (i+1 >= argc)
                        usage(argv[0]);
                    gListenInterface[gInterfaceCount++] = argv[++i];
                    break;
                case 'j':        // Late join value
                    if (i+1 >= argc)
                        usage(argv[0]);
                    gLateJoin = atol(argv[++i]);
                    if (gLateJoin > SENDER_MAX_LATE_JOINER_PERCENTAGE)
                    {
                        gLateJoin = SENDER_MAX_LATE_JOINER_PERCENTAGE;
                        printf("Exceeded maximum late join value (%d%%)!\n", gLateJoin);
                        printf("   Setting value to maximum allowed\n");
                    }
                    break;
                case 'm':        // multicast group to join
                    if (i+1 >= argc)
                        usage(argv[0]);
                    gMulticast = argv[++i];
                    break;
                case 'n':        // Number of messages to send/recv
                    if (i+1 >= argc)
                        usage(argv[0]);
                    gCount = atoi(argv[++i]);
                    break;
                case 'p':        // Port number to use
                    if (i+1 >= argc)
                        usage(argv[0]);
                    gPort = argv[++i];
                    break;
                case 's':        // sender
                    bSender = TRUE;
                    break;
                case 't':        // Multicast ttl
                    if (i+1 >= argc)
                        usage(argv[0]);
                    gTtl = atoi(argv[++i]);
                    break;
                case 'w':        // Send window size
                    if ((i+1 >= argc) || (strlen(argv[i]) != 3))
                        usage(argv[0]);
                    bSetSendWindow = TRUE;
                    switch (tolower(argv[i][2]))
                    {
                        case 'b':           // Window size in bytes
                            gWindowSizeBytes = atol(argv[++i]);
                            break;
                        case 's':           // Window size in seconds
                            gWindowSizeMSec = atol(argv[++i]) * 1000;
                            break;
                        case 'r':           // Window size in bytes/sec
                            gWindowRateKbitsSec = (atol(argv[++i])/1000) * 8;
                            break;
                        default:
                            usage(argv[0]);
                            break;
                    }
                    break;
                case 'z':        // Buffer size for send/recv
                    if (i+1 >= argc)
                        usage(argv[0]);
                    gBufferSize = atol(argv[++i]);
                    break;
                default:
                    usage(argv[0]);
                    break;
            }
        }
    }
    return;
}

//
// Function: SetSendInterface
//
// Description:
//    This routine sets the sending interface. This option may only be set
//    on senders.
//
int SetSendInterface(SOCKET s, struct addrinfo *iface)
{
    int   rc;

    // Set the send interface
    rc = setsockopt(
            s, 
            IPPROTO_RM, 
            RM_SET_SEND_IF,
            (char *)&((SOCKADDR_IN *)iface->ai_addr)->sin_addr.s_addr,
            sizeof(ULONG)
            );
    if (rc == SOCKET_ERROR)
    {
        printf("setsockopt failed: %d\n", WSAGetLastError());
    }
    else
    {
        printf("Set sending interface to: ");
        PrintAddress(iface->ai_addr, iface->ai_addrlen);
        printf("\n");
    }
    return rc;
}

//
// Function: AddReceiveInterface
//
// Description:
//    This routine adds the given interface to the receiving interfac 
//    list. This option is valid only for receivers.
//
int AddReceiveInterface(SOCKET s, struct addrinfo *iface)
{
    int rc;

    rc = setsockopt(
            s,
            IPPROTO_RM,
            RM_ADD_RECEIVE_IF,
            (char *)&((SOCKADDR_IN *)iface->ai_addr)->sin_addr.s_addr,
            sizeof(ULONG)
            );
    if (rc == SOCKET_ERROR)
    {
        printf("setsockopt: RM_ADD_RECEIVE_IF failed: %d\n", WSAGetLastError());
    }
    else
    {
        printf("Adding receive interface: ");
        PrintAddress(iface->ai_addr, iface->ai_addrlen);
        printf("\n");
    }
    return rc;
}

//
// Function: SetMulticastTtl
//
// Description:
//    This routine sets the multicast TTL value for the socket.
//
int SetMulticastTtl(SOCKET s, int af, int ttl)
{
    int   rc;

    // Set the TTL value
    rc = setsockopt(
            s,
            IPPROTO_RM, 
            RM_SET_MCAST_TTL,
            (char *)&ttl, 
            sizeof(ttl)
            );
    if (rc == SOCKET_ERROR)
    {
        fprintf(stderr, "SetMulticastTtl: setsockopt failed: %d\n", WSAGetLastError());
    }
    else
    {
        printf("Set multicast ttl to: %d\n", ttl);
    }
    return rc;
}

//
// Function: SetFecParamters
//
// Description:
//    This routine sets the requested FEC parameters on a sender socket.
//    A client does not have to do anything special when the sender enables
//    or disables FEC.
//
int SetFecParameters(SOCKET s, int blocksize, int groupsize, int ondemand, int proactive)
{
    RM_FEC_INFO fec;
    int         rc;

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

⌨️ 快捷键说明

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