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

📄 asyncserver.cpp

📁 这个是网络编程
💻 CPP
📖 第 1 页 / 共 3 页
字号:
        return;

    printf("\n");

    bps = gBytesSent / elapsed;
    printf("Average BPS sent: %lu [%lu]\n", bps, gBytesSent);

    bps = gBytesRead / elapsed;
    printf("Average BPS read: %lu [%lu]\n", bps, gBytesRead);

    elapsed = (tick - gStartTimeLast) / 1000;

    if (elapsed == 0)
        return;

    bps = gBytesSentLast / elapsed;
    printf("Current BPS sent: %lu\n", bps);

    bps = gBytesReadLast / elapsed;
    printf("Current BPS read: %lu\n", bps);

    printf("Current Connections: %lu\n", gCurrentConnections);

    InterlockedExchange(&gBytesSentLast, 0);
    InterlockedExchange(&gBytesReadLast, 0);

    gStartTimeLast = tick;
}

// 
// Function: WindowProc
//
// Description:
//    This is the window procedure which handles the window messages for
//    our hidden window. It handles all the WM_SOCKET messages and performs
//    the correct actions for each message type (FD_READ, FD_WRITE, etc.).
//
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    SOCKET_OBJ  *sockobj=NULL,
                *newsock=NULL;
    int          rc;

    if (uMsg == WM_SOCKET)
    {
        // Check for an error on the socket
        if (WSAGETSELECTERROR(lParam))
        {
            // An error occured on the socket, close it down
            fprintf(stderr, "Socket failed with error %d\n", WSAGETSELECTERROR(lParam));
            closesocket(wParam);
            RemoveSocketObjByHandle(wParam);
        }
        else
        {
            // Find the socket object for this event
            sockobj = FindSocketObj(wParam);
            if (sockobj == NULL)
                return 0;

            switch (WSAGETSELECTEVENT(lParam))
            {
                case FD_ACCEPT:

                    // Get a new object for the client socket
                    newsock = GetSocketObj(INVALID_SOCKET);

                    newsock->s = accept(
                            wParam, 
                            (SOCKADDR *)&newsock->addr, 
                           &newsock->addrlen
                            );
                    if (newsock->s == INVALID_SOCKET)
                    {
                        fprintf(stderr, "accept failed: %d\n", WSAGetLastError());
                        break;
                    }

                    InterlockedIncrement(&gCurrentConnections);

                    // Create a socket information structure to associate with the
                    // socket for processing I/O.
                    InsertSocketObj(newsock);

                    /*
                    printf("Accepted connection from: ");
                    PrintAddress((SOCKADDR *)&newsock->addr, newsock->addrlen);
                    printf("\n");
                    */

                    rc = WSAAsyncSelect(
                            newsock->s, 
                            hwnd, 
                            WM_SOCKET, 
                            FD_READ | FD_WRITE | FD_CLOSE
                            );
                    if (rc == SOCKET_ERROR)
                    {
                        fprintf(stderr, "WSAAsyncSelect failed: %d\n", WSAGetLastError());
                        return -1;
                    }

                    break;
                case FD_READ:
                    rc = ReceivePendingData(sockobj);
                    if (rc == -1)
                    {
                        RemoveSocketObj(sockobj);
                        break;
                    }
                    else if (rc != WSAEWOULDBLOCK)
                    {
                        PostMessage(hwnd, WM_SOCKET, wParam, FD_READ);
                    }
                    //
                    // Don't break fall through and attempt to send data
                    //
                case FD_WRITE:
                    //
                    // Send routine automatically tries to send all queued buffers.
                    //
                    rc = SendPendingData(sockobj);
                    if (rc == -1)
                    {
                        RemoveSocketObj(sockobj);
                    }
                    break;
                case FD_CLOSE:
                    sockobj->closing = TRUE;
                    //
                    // Post an FD_READ message to force another receive
                    //    This is to ensure we recv() until 0 is returned.
                    //
                    PostMessage(hwnd, WM_SOCKET, wParam, FD_READ);
                    break;
                default:
                    printf("Unknown message received: %d\n", WSAGETSELECTEVENT(lParam));
                    break;
            }
        }
        return 0;
    }

    return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

//
// Function: MakeWorkerWindow
//
// Description:
//    Create a hidden window to receive our socket messages.
//
HWND MakeWorkerWindow(void)
{
    WNDCLASS wndclass;
    CHAR *ProviderClass = "AsyncSelect";
    HWND Window;

    wndclass.style = CS_HREDRAW | CS_VREDRAW;
    wndclass.lpfnWndProc = (WNDPROC)WindowProc;
    wndclass.cbClsExtra = 0;
    wndclass.cbWndExtra = 0;
    wndclass.hInstance = NULL;
    wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
    wndclass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
    wndclass.lpszMenuName = NULL;
    wndclass.lpszClassName = ProviderClass;

    if (RegisterClass(&wndclass) == 0)
    {
        fprintf(stderr, "RegisterClass() failed with error %d\n", GetLastError());
        return NULL;
    }

    // Create a window.

    if ((Window = CreateWindow(
                    ProviderClass,
                    "",
                    WS_OVERLAPPEDWINDOW,
                    CW_USEDEFAULT,
                    CW_USEDEFAULT,
                    CW_USEDEFAULT,
                    CW_USEDEFAULT,
                    NULL,
                    NULL,
                    NULL,
                    NULL)) == NULL)
    {      
        fprintf(stderr, "CreateWindow() failed with error %d\n", GetLastError());
        return NULL;
    }

    return Window;
}

// 
// Function: StatisticsThread
//
// Description:
//    Simple thread to print the statistics out. In this model there isn't
//    a good place to incorporate it into the normal program flow.
//
DWORD WINAPI StatisticsThread(LPVOID lpParam)
{
    while (1)
    {
        SleepEx(5000, TRUE);

        PrintStatistics();
    }
    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_OBJ      *sockobj=NULL,
                    *sptr=NULL,
                    *tmp=NULL;
    HANDLE           hThread;
    ULONG            lastprint=0;
    MSG              msg;
    int              rc;
    struct addrinfo *res=NULL,
                    *ptr=NULL;

    ValidateArgs(argc, argv);

    InitializeCriticalSection(&gSocketCritSec);

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

    gWorkerWindow = MakeWorkerWindow();

    printf("Local address: %s; Port: %s; Family: %d\n",
            gBindAddr, gBindPort, gAddressFamily);

    res = ResolveAddress(gBindAddr, gBindPort, gAddressFamily, gSocketType, gProtocol);
    if (res == NULL)
    {
        fprintf(stderr, "ResolveAddress failed to return any addresses!\n");
        return -1;
    }

    // For each local address returned, create a listening/receiving socket
    ptr = res;
    while (ptr)
    {
        PrintAddress(ptr->ai_addr, ptr->ai_addrlen); printf("\n");

        sockobj = GetSocketObj(INVALID_SOCKET);

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


        InsertSocketObj(sockobj);

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

        if (gProtocol == IPPROTO_TCP)
        {
            rc = listen(sockobj->s, 200);
            if (rc == SOCKET_ERROR)
            {
                fprintf(stderr, "listen failed: %d\n", WSAGetLastError());
                return -1;
            }

            // Register for notification
            rc = WSAAsyncSelect(
                    sockobj->s,
                    gWorkerWindow,
                    WM_SOCKET,
                    FD_ACCEPT | FD_CLOSE
                    );
            if (rc == SOCKET_ERROR)
            {
                fprintf(stderr, "WSAAsyncSelect failed: %d\n", WSAGetLastError());
                return -1;
            }
        }
        else
        {
            // Register for notification
            rc = WSAAsyncSelect(
                    sockobj->s,
                    gWorkerWindow,
                    WM_SOCKET,
                    FD_READ | FD_WRITE | FD_CLOSE
                    );
            if (rc == SOCKET_ERROR)
            {
                fprintf(stderr, "WSAAsyncSelect failed: %d\n", WSAGetLastError());
                return -1;
            }
        }

        ptr = ptr->ai_next;
    }
    // free the addrinfo structure for the 'bind' address
    freeaddrinfo(res);

    gStartTime = gStartTimeLast = lastprint = GetTickCount();

    // Start a thread to print statistics
    hThread = CreateThread(NULL, 0, StatisticsThread, NULL, 0, NULL);
    if (hThread == NULL)
    {
        fprintf(stderr, "CreateThread failed: %d\n", WSAGetLastError());
        return -1;
    }
    CloseHandle(hThread);

    while(rc = GetMessage(&msg, NULL, 0, 0))
    {
        if (rc == -1)
        {
            fprintf(stderr, "GetMessage() failed with error %d\n", GetLastError());
            return -1;
        }

        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    WSACleanup();

    DeleteCriticalSection(&gSocketCritSec);

    return 0;
}

⌨️ 快捷键说明

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