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

📄 qosmcast.c

📁 《Windows网络编程技术》附书源码源码. 运行环境:9x/Me/NT/2000/XP/ 源码语言:简体中文 第十二章
💻 C
📖 第 1 页 / 共 2 页
字号:
    WSAEVENT         hEvent;
    WSABUF           wbuf;
    DWORD            dwBytes=0,
                     dwFlags=0,
                     dwFromLen,
                     dwBytesRecv,
                     dwBytesSent;
    QOS             *lpqos=NULL;
    char             rcvbuf[DATA_BUFFER_SZ],
                     sndbuf[DATA_BUFFER_SZ],
                     qosbuf[QOS_BUFFER_SZ];
    int              ret,
                     i;
    static BOOL      bOkToSend=FALSE;

    //
    // Create the event used to signal socket events
    //
    hEvent = WSACreateEvent();
    if (hEvent == WSA_INVALID_EVENT)
    {
        printf("WSACreateEvent() failed: %d\n", WSAGetLastError());
        return;
    }

    local.sin_family = AF_INET;
    local.sin_port = htons(5150);
    local.sin_addr.s_addr = htonl(INADDR_ANY);
   
    ret = bind(s, (SOCKADDR *)&local, sizeof(local));
    if (ret == SOCKET_ERROR)
    {
        printf("bind() failed: %d\n", WSAGetLastError());
        return;
    }

    // Check to see if we're supposed to set QOS before joining the 
    // multicast group or if we just want to enabled FD_QOS on the
    // socket.
    //
    lpqos = NULL;
    if (iSetQos == SET_QOS_BEFORE)
    {
        if (bSender)
            lpqos = &sendQos;
        else
            lpqos = &recvQos;
        //
        // Call this routine to set QOS for both senders and receivers.
        // In the case of senders, no provider specific objects are used.
        //
        if (SetQosReceivers(s, lpqos) == FALSE)
            return;
        lpqos = NULL;
    }
    else if (iSetQos == SET_QOS_EVENT)
    {
        // Only want to receive the FD_QOS event and set QOS
        // at a later time.
        //
        if (bSender)
        {
            lpqos = &sendQos;
            sendQos.SendingFlowspec.ServiceType = 
                sendQos.SendingFlowspec.ServiceType;
        }
        else
        {
            lpqos = &recvQos;
            recvQos.ReceivingFlowspec.ServiceType = 
                recvQos.ReceivingFlowspec.ServiceType;
        }
        if (SetQosReceivers(s, lpqos) == FALSE)
            return;
        lpqos = NULL;
    }
    else if (iSetQos == SET_QOS_DURING)
    {
        if (bSender)
            lpqos = &sendQos;
        else
            lpqos = &recvQos;
        //
        // If setting QOS in the WSAJoinLeaf call we need to set
        // the RSVP_RESERVE_INFO structure beforehand.
        //
        if (iNumSenders > 0)
            SetQosReserveInfo(lpqos);
    }
    else
        lpqos  = NULL;
    // Setup the flags to indicate whether we are sending or receiving
    //
    if (bSender)
        dwFlags = JL_SENDER_ONLY;
    else
        dwFlags = JL_RECEIVER_ONLY;

    for(i=0; i < iNumGroups ;i++)
    {
        // Setup the mutlicast address structure which will be used 
        // throughout this function.
        //
        mcast.sin_family = AF_INET;
        mcast.sin_port   = htons(5150);
        mcast.sin_addr.s_addr = inet_addr(szMulticastAddrs[i]);
        //
        // Join the multicast group!
        //
        ret = WSAJoinLeaf(s, (SOCKADDR *)&mcast, sizeof(mcast), NULL, NULL,
                    lpqos, NULL, dwFlags);
        if (ret == SOCKET_ERROR)
        {
            printf("WSAJoinLeaf() failed: %d\n", WSAGetLastError());
            return;
        }
    }
    if (lpqos)
        PrintQos(lpqos);

    if (iSetQos == SET_QOS_AFTER)
    {
        // Setting QOS after joining the group. Since WSAJoinLeaf does
        // an implicit bind, we only have to call SIO_SET_QOS.
        //
        if (bSender)
            lpqos = &sendQos;
        else
            lpqos = &recvQos;

        if (SetQosReceivers(s, lpqos) == FALSE)
            return;
    }
    // Register for the events we want to receive
    //
    ret = WSAEventSelect(s, hEvent, FD_QOS | FD_READ | FD_WRITE);
    if (ret == SOCKET_ERROR)
    {
        printf("WSAEventSelect() failed: %d\n", WSAGetLastError());
        return;
    }
    // Loop until done!
    //
    while (1)
    {
        // Wait until an event shows up
        //
        ret = WSAWaitForMultipleEvents(1, &hEvent, FALSE, WSA_INFINITE, FALSE);
        if (ret == WSA_WAIT_FAILED)
        {
            printf("WSAWaitForMultipleEvents() failed: %d\n",
                WSAGetLastError());
            return;
        }
        // Enumerate any events that have occured.
        //
        ret = WSAEnumNetworkEvents(s, hEvent, &ne);
        if (ret == SOCKET_ERROR)
        {
            printf("WSAEnumNetworkEvents() failed: %d\n", WSAGetLastError());
            return;
        }

        if (ne.lNetworkEvents & FD_READ)
        {
            // Got a FD_READ event. Check for errors and then read pending data.
            //
            if (ne.iErrorCode[FD_READ_BIT])
            {
                printf("FD_READ error: %d\n", ne.iErrorCode[FD_READ_BIT]);
            }
            dwFromLen = sizeof(from);
            wbuf.buf = rcvbuf;
            wbuf.len = DATA_BUFFER_SZ;
            dwFlags = 0;
        
            ret = WSARecvFrom(s, &wbuf, 1, &dwBytesRecv, &dwFlags, (SOCKADDR *)&from,
                        &dwFromLen, NULL, NULL);
            if (ret == SOCKET_ERROR)
            {
                printf("WSARecvFrom() failed: %d\n", WSAGetLastError());
                return;
            }
            rcvbuf[dwBytesRecv] = 0;
            printf("READ [%s] from [%s]\n", rcvbuf, inet_ntoa(from.sin_addr));
        }
        if (ne.lNetworkEvents & FD_WRITE)
        {
            // Got an FD_WRITE event. If we're the sender check to see if
            // we're waiting for confirmation before sending..if so don't send
            // until such a time. 
            //
            if (ne.iErrorCode[FD_WRITE_BIT])
            {
                printf("FD_WRITE error: %d\n", ne.iErrorCode[FD_WRITE_BIT]);
            }
            if ((bSender) && (!bWaitToSend))
            {
                memset(sndbuf, '#', DATA_BUFFER_SZ);
                wbuf.buf = sndbuf;
                wbuf.len = DATA_BUFFER_SZ - 1;

                for(i=0; i < iNumGroups ;i++)
                {
                    mcast.sin_family = AF_INET;
                    mcast.sin_port = htons(5150);
                    mcast.sin_addr.s_addr = inet_addr(szMulticastAddrs[i]);
                    ret = WSASendTo(s, &wbuf, 1, &dwBytesSent, 0, (SOCKADDR *)&mcast,
                            sizeof(mcast), NULL, NULL);
                    if (ret == SOCKET_ERROR)
                    {
                        printf("WSASendTo() failed: %d\n", WSAGetLastError());
                        return;
                    }
                    printf("WSASendTo() wrote: %d bytes to %s\n", dwBytesSent, 
                        inet_ntoa(mcast.sin_addr));
                }
            }
        }
        if (ne.lNetworkEvents & FD_QOS)
        {
            // Got an FD_QOS event. This can be triggered by a great
            // variety of things. Typically if an error code is set it is
            // actually more of a status such as notification that there
            // are senders or receivers out there so we need to check
            // for quite a few "error" codes to make sure we're doing
            // the right thing.
            //
            bOkToSend = FALSE;
            printf("FD_QOS event\n");
            if (ne.iErrorCode[FD_QOS_BIT])
            {
                switch (ne.iErrorCode[FD_QOS_BIT])
                {
                    case WSA_QOS_RECEIVERS:
                        printf("\tQOS recievers\n");
                        bOkToSend = TRUE;
                        break;
                    case WSA_QOS_SENDERS:
                        printf("\tQOS senders\n");
                        break;
                    case WSA_QOS_NO_SENDERS:
                        printf("\tQOS no senders\n");
                        break;
                    case WSA_QOS_NO_RECEIVERS:
                        printf("\tQOS no receivers\n");
                        break;
                    case WSA_QOS_REQUEST_CONFIRMED:
                        printf("\tQOS request confirmed\n");
                        break;
                    case WSA_QOS_ADMISSION_FAILURE:
                        printf("\tQOS admission failure\n");
                        return;
                    case WSA_QOS_POLICY_FAILURE:
                        printf("\tQOS policy failure\n");
                        return;
                    case WSA_QOS_BAD_STYLE:
                        printf("\tQOS bad style\n");
                        return;
                    case WSA_QOS_BAD_OBJECT:
                        printf("\tQOS bad object\n");
                        return;
                    case WSA_QOS_TRAFFIC_CTRL_ERROR:
                        printf("\tQOS traffic control error\n");
                        return;
                    case WSA_QOS_GENERIC_ERROR:
                        printf("\tQOS generic error\n");
                        return;
                    default:
                        printf("FD_QOS error: %d\n", ne.iErrorCode[FD_QOS_BIT]);
                        return;
                }
            }
            lpqos = (QOS *)qosbuf;
            lpqos->ProviderSpecific.buf = &qosbuf[sizeof(QOS)];
            lpqos->ProviderSpecific.len = sizeof(qosbuf) - sizeof(QOS);

            ret = WSAIoctl(s, SIO_GET_QOS, NULL, 0, lpqos, QOS_BUFFER_SZ,
                        &dwBytes, NULL, NULL);
            if (ret == SOCKET_ERROR)
            {
                printf("WSAIoctl() failed: %d\n", WSAGetLastError());
                return;
            }
            PrintQos(lpqos);
            //
            // If we're the sender and we've specified to wait for confirmation
            // before sending not only do we need to check the error code checked
            // earlier, but it is possible to return status information in the
            // provider specific buffer so we check that too.
            //
            if (bSender)
            {
                if (ChkForQosStatus(lpqos, WSA_QOS_RECEIVERS))
                    bOkToSend = TRUE;
                //
                // If we got confirmation, send data
                //
                if (bWaitToSend && bOkToSend)
                {
                    memset(sndbuf, '@', DATA_BUFFER_SZ);
                    wbuf.buf = sndbuf;
                    wbuf.len = DATA_BUFFER_SZ - 1;

                    for(i=0; i < iNumGroups ;i++)
                    {
                        mcast.sin_family = AF_INET;
                        mcast.sin_port = htons(5150);
                        mcast.sin_addr.s_addr = inet_addr(szMulticastAddrs[i]);

                        ret = WSASendTo(s, &wbuf, 1, &dwBytesSent, 0, (SOCKADDR *)&mcast,
                                sizeof(mcast), NULL, NULL);
                        if (ret == SOCKET_ERROR)
                        {
                            printf("WSASendTo() failed: %d\n", WSAGetLastError());
                            return;
                        }
                        printf("WSASendTo() wrote: %d bytes to %s\n", dwBytesSent, 
                            inet_ntoa(mcast.sin_addr));
                    }
                }
            }
        }
    }
    return;
}

//
// Function: main
//
// Description:
//    Parse command line arguments, find a QOS enabled provider that 
//    supports multicasting, create a socket, and call the driver
//    function.
//
int main(int argc, char **argv)
{
    WSAPROTOCOL_INFO *pi=NULL;
    WSADATA           wsd;
    SOCKET            s;

    // Parse command line args and initialize Winsock.
    //
    ValidateArgs(argc, argv);

    if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)
    {
        printf("WSAStartup() failed: %d\n", GetLastError());
        return -1;
    }
    // Find a provider that supports QOS and multicasting.
    //
    pi = FindProtocolInfo(AF_INET, SOCK_DGRAM, IPPROTO_UDP,
             XP1_QOS_SUPPORTED | XP1_SUPPORT_MULTIPOINT);
    if (!pi)
    {
        printf("unable to find suitable provider!\n");
        WSACleanup();
        return -1;
    }
    printf("Provider returned: %s\n", pi->szProtocol);
    //
    // Create a socket.
    //
    s = WSASocket(FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO,
            FROM_PROTOCOL_INFO, pi, 0, WSA_FLAG_OVERLAPPED |
            WSA_FLAG_MULTIPOINT_C_LEAF | WSA_FLAG_MULTIPOINT_D_LEAF);
    if (s == SOCKET_ERROR)
    {
        printf("WSASocket() failed: %d\n", WSAGetLastError());
        WSACleanup();
        return -1;
    }
    // Initialize the sending and receiving QOS structures
    //
    InitQos();

    MulticastDriver(s);

    closesocket(s);
    WSACleanup();
    return 0;
}

⌨️ 快捷键说明

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