troubleshooting Question

Fill the socket address

Avatar of turbot_yu
turbot_yuFlag for Singapore asked on
System Programming
4 Comments1 Solution331 ViewsLast Modified:
Hi, May I know how to fill in the IP and port for the socket in the lines below.

Thanks,

Turbot

class CServerSocket  
{
   ....

    SOCKET m_hListeningSocket;
    WSAEVENT m_hAcceptEvent;
    HANDLE m_hListeningThread;
    HANDLE m_hStopListenEvent;
};

void CServerSocket::Initialize(int nPort)
{
    unsigned int dwThreadID;

    // initialize Windows Sockets
    WSADATA wsaData;
    int nResult = WSAStartup(MAKEWORD(2,2), &wsaData);
    int nError = WSAGetLastError();

    if ( nResult != 0 )     // OK
    {
        PostLogMessage(_T("Winsock initialization failed"));
        PrintErrorDescription(nError);
        return;
    }

    m_bInitialized = TRUE;
    PostLogMessage(_T("Winsock initialization succeeded"));

    // create listening socket
    m_hListeningSocket = WSASocket(
        AF_INET,
        SOCK_STREAM,
        0,
        NULL,
        0,
        WSA_FLAG_OVERLAPPED);         // non-blocking

    nError = WSAGetLastError();

    if ( m_hListeningSocket == INVALID_SOCKET )
    {
        PostLogMessage(_T("Creating of listening socket failed"));
        PrintErrorDescription(nError);
        return;
    }

    // create Accept event
    m_hAcceptEvent = WSACreateEvent();
    nError = WSAGetLastError();

    if ( m_hAcceptEvent == WSA_INVALID_EVENT )
    {
        PostLogMessage(_T("Creating of Accept event failed"));
        PrintErrorDescription(nError);
        return;
    }

    // Associate FD_ACCEPT socket event with m_hAcceptEvent. Now m_hAcceptEvent
    // will be signaled when new client request is received
    // by m_hListeningSocket.
    // m_hAcceptEvent is signaled when accept() may be called whith
    // expectation if immidiate success.
    nResult = WSAEventSelect(m_hListeningSocket,
                             m_hAcceptEvent,
                             FD_ACCEPT);
   
    if ( nResult == SOCKET_ERROR )
    {
        PostLogMessage(_T("WSAEventSelect failed"));
        PrintErrorDescription(nError);
        return;
    }

    // fill SOCKADDR_IN structure
    SOCKADDR_IN     saServer;      

    saServer.sin_port = htons((unsigned short)nPort);
    saServer.sin_family = AF_INET;
    saServer.sin_addr.s_addr = INADDR_ANY;

    // bind SOCKADDR_IN to the listening socket
    nResult = bind(m_hListeningSocket,
                   (LPSOCKADDR)&saServer,
                   sizeof(struct sockaddr));

    if ( nResult == SOCKET_ERROR )
    {
        PostLogMessage(_T("bind function failed"));
        PrintErrorDescription(nError);
        return;
    }

    // Start listening
    nResult = listen(m_hListeningSocket, SOMAXCONN);

    if ( nResult == SOCKET_ERROR )
    {
        PostLogMessage(_T("listen function failed"));
        PrintErrorDescription(nError);
        return;
    }

    // create Stop Listening Thread event
    m_hStopListenEvent = CreateEvent(NULL, TRUE, FALSE, NULL);  // manually reset, initially unsignaled

    if ( ! m_hStopListenEvent )
    {
        PostLogMessage(_T("CreateEvent failed"));
        return;
    }

    // run listening thread

    m_hListeningThread = (HANDLE)_beginthreadex(
        NULL,
        0,
        ListenThreadProc,
        (void*) this,      
        0,
        &dwThreadID);

    if ( m_hListeningThread == NULL )
    {
        PostLogMessage(_T("_beginthreadex for listening threrad failed"));
        return;
    }

    // Show OK message
    PostLogMessage(_T("Server is running"));
}

// this is static function
unsigned CServerSocket::ListenThreadProc(LPVOID lpVoid)
{
    CServerSocket* p  = (CServerSocket*) lpVoid;
    p->ListenThreadFunction();

    return 0;
}

void CServerSocket::ListenThreadFunction()
{
    WSANETWORKEVENTS events;
    DWORD dwResult;
    int nError;
    BOOL bContinue = TRUE;

    HANDLE hEvents[2];
    hEvents[0] = m_hAcceptEvent;
    hEvents[1] = m_hStopListenEvent;

    PostLogMessage(_T("ListenThreadFunction started"));

    while ( bContinue )
    {
        // Wait for asynchronous socket notification (see WSAEventSelect call)
        // and our own stop event

        dwResult = WSAWaitForMultipleEvents(
            2,
            hEvents,
            FALSE,
            INFINITE,
            FALSE);

        nError = WSAGetLastError();
       
        switch ( dwResult )
        {
        case WAIT_OBJECT_0:
            // m_hAcceptEvent event is signaled, new client is connected

            dwResult = WSAEnumNetworkEvents(m_hListeningSocket, m_hAcceptEvent, &events);  // get event type

            nError = WSAGetLastError();

            WSAResetEvent(m_hAcceptEvent);

            if ( dwResult == SOCKET_ERROR )
            {
                PostLogMessage(_T("Error calling WSAEnumNetworkEvents"));
                PrintErrorDescription(nError);
                bContinue = FALSE;
                break;
            }

            // handle signaled network events (we sobscribed to only one - FD_ACCEPT)

            if ( events.lNetworkEvents & FD_ACCEPT )
            {
                // Handle Accept network event. If function returns FALSE (failed), exit
                if ( ! OnAccept(events.iErrorCode[FD_ACCEPT_BIT]) )
                {
                    bContinue = FALSE;
                    break;
                }
            }

            break;

        case WAIT_OBJECT_0 + 1:
            // m_hStopListenEvent is signaled
            bContinue = FALSE;
            break;

        default:
            PostLogMessage(_T("Error calling WSAWaitForMultipleEvents"));
            PrintErrorDescription(nError);
            bContinue = FALSE;
            break;
        }

    }

    PostLogMessage(_T("ListenThreadFunction finished"));
}

void CServerSocket::Cleanup()
{
    int i;
    m_bClosed = TRUE;

    if ( m_hListeningThread )
    {
        // stop listening thread
        SetEvent(m_hStopListenEvent);

        if ( WaitForSingleObject(m_hListeningThread, 3000) != WAIT_OBJECT_0 )
        {
            TerminateThread(m_hListeningThread, 0);
            TRACE(_T("Listening thread is terminated\n"));
        }

        CloseHandle(m_hListeningThread);
    }

    // release events
    if ( m_hStopListenEvent )
    {
        CloseHandle(m_hStopListenEvent);
    }

    if ( m_hAcceptEvent != WSA_INVALID_EVENT )
    {
        WSACloseEvent(m_hAcceptEvent);
    }

    // close listening socket
    if ( m_hListeningSocket != INVALID_SOCKET )
    {
        closesocket(m_hListeningSocket);
    }

    }

    // Close completion port
    if ( m_hCompletionPort )
    {
        CloseHandle(m_hCompletionPort);
    }

    // Sockets cleanup
    if ( m_bInitialized )
        WSACleanup();
}

BOOL CServerSocket::OnAccept(int nErrorCode)
{
    int nResult;
    int nError;

    if ( nErrorCode != 0 )
    {
        PostLogMessage(_T("Accept event error"));
        PrintErrorDescription(nErrorCode);
        return FALSE;
    }

    PostLogMessage(_T("Client connected"));

    // accept new connection
    SOCKADDR_IN SockAddr;           // gets information about client
    SOCKET clientSocket;
    int nAddrLen = sizeof(SOCKADDR_IN);

    clientSocket = accept(m_hListeningSocket,
                          (LPSOCKADDR)&SockAddr,
                          &nAddrLen);

    nError = WSAGetLastError();

    if ( clientSocket == INVALID_SOCKET )
    {
        PostLogMessage(_T("accept function failed"));
        PrintErrorDescription(nError);
        return TRUE;
    }

    // work with clientSocket here, but don't keep caller and return quickly.
    // possibly you need to create thread for client socket and return.
}

Join the community to see this answer!
Join our exclusive community to see this answer & millions of others.
Unlock 1 Answer and 4 Comments.
Join the Community
Learn from the best

Network and collaborate with thousands of CTOs, CISOs, and IT Pros rooting for you and your success.

Andrew Hancock - VMware vExpert
See if this solution works for you by signing up for a 7 day free trial.
Unlock 1 Answer and 4 Comments.
Try for 7 days

”The time we save is the biggest benefit of E-E to our team. What could take multiple guys 2 hours or more each to find is accessed in around 15 minutes on Experts Exchange.

-Mike Kapnisakis, Warner Bros