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

📄 bclient.cpp

📁 这个是网络编程
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    // send three zero byte datagrams.
    if (gProtocol == IPPROTO_TCP)
    {
        shutdown(s, SD_SEND);
    }
    else
    {
        for(i=0; i < 3 ;i++)
        {
            rc = sendto(
                    s,
                    buf,
                    0,
                    0,
                    gConnectedEndpoint->ai_addr,
                    gConnectedEndpoint->ai_addrlen
                    );
        }
    }

    // Free the send buffer
    HeapFree(GetProcessHeap(), 0, buf);

    ExitThread(0);
    return 0;
}

//
// Function: ReceiveThread
//
// Description:
//    This is the receive thread that attempts to receive all data on
//    a given socket. For TCP this is done until the socket is closed
//    (and the recv call returns an error or 0). For UDP, receives
//    are performed until a zero byte datagram is received.
//
DWORD WINAPI ReceiveThread(LPVOID lpParam)
{
    SOCKET      s;
    char       *buf=NULL;
    int         buflen=0,
                rc;

    s = (SOCKET) lpParam;

    // Allocate the receive buffer for this socket
    buflen = gBufferSize;
    buf = (char *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BYTE) * buflen);
    if (buf == NULL)
    {
        fprintf(stderr, "ReadThread: HeapAlloc failed: %d\n", WSAGetLastError());
        ExitProcess(-1);
    }

    while (1)
    {
        if (gProtocol == IPPROTO_UDP)
        {
            SOCKADDR_STORAGE addr;
            int              addrlen;

            addrlen = sizeof(addr);
            rc = recvfrom(
                    s,
                    buf,
                    buflen,
                    0,
                    (SOCKADDR *)&addr,
                   &addrlen
                    );
        } 
        else if (gProtocol == IPPROTO_TCP)
        {
            rc = recv(
                    s,
                    buf,
                    buflen,
                    0
                    );
        }
        if ((rc == SOCKET_ERROR) || (rc == 0))
        {
            // Either a zero byte datagram was read (UDP), the connection was
            // gracefully closed (TCP), or an error occured on the recv
            break;
        }
        else
        {
            InterlockedExchangeAdd(&gBytesRead, rc);
        }
    }

    // Free the receive buffer
    HeapFree(GetProcessHeap(), 0, buf);

    ExitThread(0);
    return 0;
}

//
// Function: main
//
// Description:
//      This is the main program. It parses the command line and creates
//      the main socket. For UDP this socket is used to receive datagrams.
//      For TCP the socket is used to accept incoming client connections.
//      Each client TCP connection is handed off to a worker thread which
//      will receive any data on that connection until the connection is
//      closed.
//
int __cdecl main(int argc, char **argv)
{
    WSADATA          wsd;
    SOCKET           s;
    HANDLE           hThreads[2];
    int              rc;                            // return code
    struct addrinfo *reslocal=NULL,
                    *resremote=NULL,
                    *ptr=NULL;

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

    // Load Winsock
    if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)
    {
        fprintf(stderr, "unable to load Winsock!\n");
        return -1;
    }

    // Resolve the server's name
    resremote = ResolveAddress(gServerAddr, gBindPort, gAddressFamily, gSocketType, gProtocol);
    if (resremote == NULL)
    {
        fprintf(stderr, "ResolveAddress failed to return any addresses!\n");
        return -1;
    }

    // Iterate through each address resolved from the server's name
    ptr = resremote;
    while (ptr)
    {
        printf("Local address: %s; Port: %s; Family: %d\n",
                gBindAddr, gBindPort, gAddressFamily);

        // Resolve the local address to bind to
        reslocal = ResolveAddress(gBindAddr, "0", ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
        if (reslocal == NULL)
        {
            fprintf(stderr, "ResolveAddress failed to return any addresses!\n");
            return -1;
        }

        PrintAddress(reslocal->ai_addr, reslocal->ai_addrlen); printf("\n");

        // create the socket
        s = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
        if (s == INVALID_SOCKET)
        {
            fprintf(stderr, "socket failed: %d\n", WSAGetLastError());
            return -1;
        }

        // bind the socket to a local address and port
        rc = bind(s, reslocal->ai_addr, reslocal->ai_addrlen);
        if (rc == SOCKET_ERROR)
        {
            fprintf(stderr, "bind failed: %d\n", WSAGetLastError());
            return -1;
        }

        // free the addrinfo structure for the 'bind' address
        freeaddrinfo(reslocal);

        if ((gProtocol == IPPROTO_TCP) || (bUdpConnect))
        {
            rc = connect(s, ptr->ai_addr, ptr->ai_addrlen);
            if (rc == SOCKET_ERROR)
            {
                printf("connect failed: %d\n", WSAGetLastError());
                closesocket(s);
                s = INVALID_SOCKET;
            }
            else
            {
                break;
            }
        }
        else
        {
            // Option is UDP with no connect, just take first address and go with it
            break;
        }

        // move to the next address resolved
        ptr = ptr->ai_next;
    }

    // See if we've got a good connection
    if (s == INVALID_SOCKET)
    {
        fprintf(stderr, "Unable to connect to server via resolved address(es)\n");
        return -1;
    }

    gConnectedEndpoint = ptr;

    gStartTime = GetTickCount();

    // Create the sending thread
    hThreads[0] = CreateThread(NULL, 0, SendThread, (LPVOID)s, 0, NULL);
    if (hThreads[0] == NULL)
    {
        fprintf(stderr, "CreateThread failed: %d\n", GetLastError());
        return -1;
    }
    hThreads[1] = CreateThread(NULL, 0, ReceiveThread, (LPVOID)s, 0, NULL);
    if (hThreads[1] == NULL)
    {
        fprintf(stderr, "CreateThread failed: %d\n", GetLastError());
        return -1;
    }

    while (1)
    {
        rc = WaitForMultipleObjects(2, hThreads, TRUE, 5000);
        if (rc == WAIT_FAILED)
        {
        }
        else if (rc == WAIT_TIMEOUT)
        {
            ULONG       bps, tick, elapsed;

            tick = GetTickCount();

            elapsed = (tick - gStartTime) / 1000;

            bps = gBytesRead / elapsed;
            printf("bytes per second read: %lu\n", bps);

            bps = gBytesSent / elapsed;
            printf("bytes per second sent: %lu\n", bps);
        }
        else
        {
            break;
        }
    }

    CloseHandle(hThreads[0]);
    CloseHandle(hThreads[1]);

    freeaddrinfo(resremote);

    closesocket(s);

    printf("\n");
    printf("total bytes sent %lu\n", gBytesSent);
    printf("total bytes read %lu\n", gBytesRead);

    WSACleanup();
    return 0;
}

⌨️ 快捷键说明

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