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

📄 qostcp.c

📁 《Windows网络编程技术》附书源码源码. 运行环境:9x/Me/NT/2000/XP/ 源码语言:简体中文 第十二章
💻 C
📖 第 1 页 / 共 2 页
字号:
            printf("WSAIoctl() failed: %d\n", 
                WSAGetLastError());
            return CF_REJECT;
        }
    }
    return CF_ACCEPT;
}

//
// Function: Server
//
// Description:
//    This server routine handles incoming client connections.
//    First it sets up the listening socket, sets QOS when
//    appropriate, and wait for incoming clients and events.
//
void Server(SOCKET s)
{
    SOCKET        sc[MAX_CONN + 1];
    WSAEVENT      hAllEvents[MAX_CONN+1];
    SOCKADDR_IN   local,
                  client;
    int           clientsz,
                  ret,
                  i;
    DWORD         dwBytesRet;
    WSANETWORKEVENTS ne;

    // Initialize the arrays to invalid values
    //
    for(i = 0; i < MAX_CONN+1; i++)
    {
        hAllEvents[i] = WSA_INVALID_EVENT;
        sc[i] = INVALID_SOCKET;
    }
    // Array index 0 will be our listening socket
    //
    hAllEvents[0] = WSACreateEvent();
    sc[0]         = s;
    nConns        = 0;

    local.sin_family = AF_INET;
    local.sin_port = htons(5150);
    local.sin_addr.s_addr = htonl(INADDR_ANY);

    if (bind(s, (SOCKADDR *)&local, sizeof(local)) == SOCKET_ERROR)
    {
        printf("bind() failed: %d\n", WSAGetLastError());
        return;
    }
    listen(s, 7);

    if (iSetQos == SET_QOS_BEFORE)
    {
        ret = WSAIoctl(sc[0], SIO_SET_QOS, &serverQos, 
            sizeof(serverQos), NULL, 0, &dwBytesRet, NULL, NULL);
        if (ret == SOCKET_ERROR)
        {
            printf("WSAIoctl(SIO_SET_QOS) failed: %d\n", 
                WSAGetLastError());
            return;
        }
        printf("Set QOS on listening socket:\n");
        PrintQos(&serverQos);
    }

    if (WSAEventSelect(sc[0], hAllEvents[0], FD_ACCEPT) == 
        SOCKET_ERROR)
    {
        printf("WSAEventSelect() failed: %d\n", WSAGetLastError());
        return;
    }

    while (1)
    {
        ret = WSAWaitForMultipleEvents(nConns+1, hAllEvents, FALSE,
            WSA_INFINITE, FALSE); 
        if (ret == WSA_WAIT_FAILED)
        {
            printf("WSAWaitForMultipleObject() failed: %d\n",
                WSAGetLastError());
            return;
        }
        if ((i = ret - WSA_WAIT_EVENT_0) > 0)  // Client network event
            HandleClientEvents(sc, hAllEvents, i);
        else
        {
            ret = WSAEnumNetworkEvents(sc[0], hAllEvents[0], 
                &ne);
            if (ret == SOCKET_ERROR)
            {
                printf("WSAEnumNetworkevents() failed: %d\n", 
                    WSAGetLastError());
                return;
            }
            if ((ne.lNetworkEvents & FD_ACCEPT) == FD_ACCEPT)
            {
                if (ne.iErrorCode[FD_ACCEPT_BIT])
                    printf("FD_ACCEPT error: %d\n", 
                        ne.iErrorCode[FD_ACCEPT_BIT]);
                else
                    printf("FD_ACCEPT\n");

                clientsz = sizeof(client);
                sc[++nConns] = WSAAccept(s, (SOCKADDR *)&client, 
                    &clientsz, SrvCondAccept, sc[nConns]);
                if (sc[nConns] == SOCKET_ERROR)
                {
                    printf("WSAAccept() failed: %d\n", 
                        WSAGetLastError());
                    nConns--;
                    return;
                }
                hAllEvents[nConns] = WSACreateEvent();

                Sleep(10000);
                if (iSetQos == SET_QOS_AFTER)
                {
                    ret = WSAIoctl(sc[nConns], SIO_SET_QOS, 
                        &serverQos, sizeof(serverQos), NULL, 0,
                        &dwBytesRet, NULL, NULL);
                    if (ret == SOCKET_ERROR)
                    {
                        printf("WSAIoctl() failed: %d\n", 
                            WSAGetLastError());
                        return;
                    }
                }
                ret = WSAEventSelect(sc[nConns],
                    hAllEvents[nConns], FD_READ | FD_WRITE | 
                    FD_CLOSE | FD_QOS);
                if (ret == SOCKET_ERROR)
                {
                    printf("WSAEventSelect() failed: %d\n", 
                        WSAGetLastError());
                    return;
                }
            }
            if (ne.lNetworkEvents & FD_CLOSE)
                printf("FD_CLOSEn");
            if (ne.lNetworkEvents & FD_READ)
                printf("FD_READn");
            if (ne.lNetworkEvents & FD_WRITE)
                printf("FD_WRITEn");
            if (ne.lNetworkEvents & FD_QOS)
                printf("FD_QOS\n");
        }
    }
    return;
}

//
// Function: Client
//
// Description:
//    The client routine initiates the connection, sets QOS when
//    appropriate, and handle incoming events.
//
void Client(SOCKET s)
{
    SOCKADDR_IN  server,
                 local;
    WSABUF       wbuf;
    DWORD        dwBytes,
                 dwBytesSent,
                 dwBytesRecv,
                 dwFlags;
    HANDLE       hEvent;
    int          ret, i;
    char         databuf[DATA_BUFFER_SZ];
    QOS         *lpqos;
    WSANETWORKEVENTS ne;

    hEvent = WSACreateEvent();
    if (hEvent == NULL)
    {
        printf("WSACreateEvent() failed: %d\n", WSAGetLastError());
        return;
    }

    lpqos = NULL;
    if (iSetQos == SET_QOS_BEFORE)
    {
        local.sin_family = AF_INET;
        local.sin_port = htons(0);
        local.sin_addr.s_addr = htonl(INADDR_ANY);
        
        if (bind(s, (SOCKADDR *)&local, sizeof(local)) == 
            SOCKET_ERROR) 
        {
            printf("bind() failed: %d\n", WSAGetLastError());
            return;
        }
        ret = WSAIoctl(s, SIO_SET_QOS, &clientQos, 
            sizeof(clientQos), NULL, 0, &dwBytes, NULL, NULL);
        if (ret == SOCKET_ERROR)
        {
            printf("WSAIoclt(SIO_SET_QOS) failed: %d\n",
                WSAGetLastError());
            return;
        }
    }
    else if (iSetQos == SET_QOS_DURING)
        lpqos = &clientQos;
    else if (iSetQos == SET_QOS_EVENT)
    {
        clientQos.SendingFlowspec.ServiceType |= 
            SERVICE_NO_QOS_SIGNALING;
        clientQos.ReceivingFlowspec.ServiceType |= 
            SERVICE_NO_QOS_SIGNALING;

        ret = WSAIoctl(s, SIO_SET_QOS, &clientQos, 
            sizeof(clientQos), NULL, 0, &dwBytes, NULL, NULL);
        if (ret == SOCKET_ERROR)
        {
            printf("WSAIoctl() failed: %d\n", WSAGetLastError());
            return;
        }
    }

    server.sin_family = AF_INET;
    server.sin_port = htons(5150);
    server.sin_addr.s_addr = inet_addr(szServerAddr);

    printf("Connecting to: %s\n", inet_ntoa(server.sin_addr));

    ret = WSAConnect(s, (SOCKADDR *)&server, sizeof(server),
        NULL, NULL, lpqos, NULL);
    if (ret == SOCKET_ERROR)
    {
        printf("WSAConnect() failed: %d\n", WSAGetLastError());
        return;
    }


    ret = WSAEventSelect(s, hEvent, FD_READ | FD_WRITE | 
        FD_CLOSE | FD_QOS);
    if (ret == SOCKET_ERROR)
    {
        printf("WSAEventSelect() failed: %d\n", WSAGetLastError());
        return;
    }

    wbuf.buf = databuf;
    wbuf.len = DATA_BUFFER_SZ;

    memset(databuf, '#', DATA_BUFFER_SZ);
    databuf[DATA_BUFFER_SZ-1] = 0;
 
    while (1)
    {
        ret = WSAWaitForMultipleEvents(1, &hEvent, FALSE, 
            WSA_INFINITE, FALSE);
        if (ret == WSA_WAIT_FAILED)
        {
            printf("WSAWaitForMulipleEvents() failed: %d\n", 
                WSAGetLastError());
            return;
        }

        ret = WSAEnumNetworkEvents(s, hEvent, &ne);
        if (ret == SOCKET_ERROR)
        {
            printf("WSAEnumNetworkEvents() failed: %d\n", 
                WSAGetLastError());
            return;
        }
        if (ne.lNetworkEvents & FD_READ)
        {
            if (ne.iErrorCode[FD_READ_BIT])
                printf("FD_READ error: %d\n", 
                    ne.iErrorCode[FD_READ_BIT]);
            else
                printf("FD_READ\n");

            wbuf.len = 4096;
            dwFlags = 0;
            ret = WSARecv(s, &wbuf, 1, &dwBytesRecv, &dwFlags, 
                NULL, NULL);
            if (ret == SOCKET_ERROR)
            {
                printf("WSARecv() failed: %d\n", 
                    WSAGetLastError());
                return;
            }
            printf("Read: %d bytes\n", dwBytesRecv);

            wbuf.len = dwBytesRecv;
            ret = WSASend(s, &wbuf, 1, &dwBytesSent, 0, NULL, 
                NULL);
            if (ret == SOCKET_ERROR)
            {
                printf("WSASend() failed: %d\n", 
                    WSAGetLastError());
                return;
            }
            printf("Sent: %d bytes\n", dwBytesSent);
        }
        if (ne.lNetworkEvents & FD_WRITE)
        {
            if (ne.iErrorCode[FD_WRITE_BIT])
                printf("FD_WRITE error: %d\n", 
                    ne.iErrorCode[FD_WRITE_BIT]);
            else
                printf("FD_WRITE\n");

            if (!bWaitToSend)
            {
                wbuf.buf = databuf;
                wbuf.len = DATA_BUFFER_SZ;
                //
                // If the network can't support the bandwidth
                // don't send
                //
                if (!AbleToSend(s))
                {
                    printf("Network is unable to provide "
						"sufficient best effort bandwidth\n");
                    printf("before the reservation "
						"request is approved\n");
                }
                
                for(i = 0; i < 1; i++)
                {
                    ret = WSASend(s, &wbuf, 1, &dwBytesSent, 0, 
                        NULL, NULL);
                    if (ret == SOCKET_ERROR)
                    {
                        printf("WSASend() failed: %d\n", 
                            WSAGetLastError());
                        return;
                    }
                    printf("Sent: %d bytes\n", dwBytesSent);
                }
            }
        }
        if (ne.lNetworkEvents & FD_CLOSE)
        {
            if (ne.iErrorCode[FD_CLOSE_BIT])
                printf("FD_CLOSE error: %d\n", 
                    ne.iErrorCode[FD_CLOSE_BIT]);
            else
                printf("FD_CLOSE ...\n");
            closesocket(s);
            WSACloseEvent(hEvent);
            return;
        }
        if (ne.lNetworkEvents & FD_QOS)
        {
            char        buf[QOS_BUFFER_SZ];
            QOS        *lpqos = NULL;
            DWORD       dwBytes;
            BOOL        bRecvRESV = FALSE;

            if (ne.iErrorCode[FD_QOS_BIT])
            {
                printf("FD_QOS error: %d\n", 
                    ne.iErrorCode[FD_QOS_BIT]);
                if (ne.iErrorCode[FD_QOS_BIT] == WSA_QOS_RECEIVERS)
                    bRecvRESV = TRUE;
            }
            else
                printf("FD_QOS\n");

            lpqos = (QOS *)buf;
            ret = WSAIoctl(s, SIO_GET_QOS, NULL, 0,
                    buf, QOS_BUFFER_SZ, &dwBytes, NULL, NULL);
            if (ret == SOCKET_ERROR)
            {
                printf("WSAIoctl(SIO_GET_QOS) failed: %d\n", 
                    WSAGetLastError());
                return;
            }
            PrintQos(lpqos);
            //
            // Check to see if there is a status object returned 
            // in the QOS structure which may also contain the
            // WSA_QOS_RECEIVERS flag
            //
            if (ChkForQosStatus(lpqos, WSA_QOS_RECEIVERS))
                bRecvRESV = TRUE;

            if (iSetQos == SET_QOS_EVENT)
            {
                lpqos->SendingFlowspec.ServiceType = 
                    clientQos.SendingFlowspec.ServiceType;
                ret = WSAIoctl(s, SIO_SET_QOS, lpqos, dwBytes,
                        NULL, 0, &dwBytes, NULL, NULL);
                if (ret == SOCKET_ERROR)
                {
                    printf("WSAIoctl(SIO_SET_QOS) failed: %d\n", 
                        WSAGetLastError());
                    return;
                }
                //
                // Change iSetQos so we don't set QOS again if we 
                // receive another FD_QOS event
                //
                iSetQos = SET_QOS_BEFORE;
            }

            if (bWaitToSend && bRecvRESV)
            {
                wbuf.buf = databuf;
                wbuf.len = DATA_BUFFER_SZ;

                for(i = 0; i < 1; i++)
                {
                    ret = WSASend(s, &wbuf, 1, &dwBytesSent, 0, 
                        NULL, NULL);
                    if (ret == SOCKET_ERROR)
                    {
                        printf("WSASend() failed: %d\n", 
                            WSAGetLastError());
                        return;
                    }
                    printf("Sent: %d bytes\n", dwBytesSent);
                }
            }
        }
    }
    return;
}

//
// Function: main
//
// Description:
//    Initialize Winsock, parse command line arguments, create
//    a QOS TCP socket, and call the appropriate handler 
//    routine depending on the arguments supplied
//
int main(int argc, char **argv)
{
    WSADATA           wsd;
    WSAPROTOCOL_INFO *pinfo = NULL;
    SOCKET            s;

    // Parse the command line
    ValidateArgs(argc, argv);
    if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)
    {
        printf("Unable to load Winsock: %d\n", GetLastError());
        return -1;
    }
    pinfo = FindProtocolInfo(AF_INET, SOCK_STREAM, IPPROTO_TCP,
        XP1_QOS_SUPPORTED);
    if (!pinfo)
    {
        printf("unable to find suitable provider!\n");
        return -1;
    }
    printf("Provider returned: %s\n", pinfo->szProtocol); 
   
    s = WSASocket(FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO, 
        FROM_PROTOCOL_INFO, pinfo, 0, WSA_FLAG_OVERLAPPED);
    if (s == INVALID_SOCKET)
    {
        printf("WSASocket() failed: %d\n", WSAGetLastError());
        return -1;
    }
    InitQos();

    if (bServer)
        Server(s);
    else
        Client(s);

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

⌨️ 快捷键说明

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