Thread: async Client/Server app, accept() stalls?

Threaded View

Previous Post Previous Post   Next Post Next Post
  1. #1
    carry on JaWiB's Avatar
    Join Date
    Feb 2003
    Location
    Seattle, WA
    Posts
    1,972

    Question async Client/Server app, accept() stalls?

    First off, I am very inexperienced with network programming, but I thought I'd try my hand with asynchronous sockets. So, after reading some of this tutorial, I made a program that should be able to connect or wait for a connection. So I made a network class, and simply set it to connect to my local ip address if a button is pressed, or set to listen mode if the other button is pressed.

    I can tell something is working, because I receive a FD_ACCEPT message on the instance I set to listen, but then my program never seems to reach any code after I call accept():

    My window proc:
    Code:
    LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        switch (message)                  /* handle the messages */
        {
          case WM_CREATE:
            CreateWindowEx(0,                                      //more or 'extended' styles
                           TEXT("BUTTON"),                         //'class' of control to create
                           TEXT("Connect"),            //the control caption
                           WS_CHILD|WS_VISIBLE|BS_DEFPUSHBUTTON,   //control style: how it looks
                           10,                                     //control position: left
                           10,                                     //control position: top
                           100,                                    //control width
                           20,                                     //control height
                           hwnd,                                   //parent window handle
                           (HMENU)IDC_CONNECT,                                   //control's ID
                           g_hInst,                                //application instance
                           NULL); 
            CreateWindowEx(0,                                      //more or 'extended' styles
                           TEXT("BUTTON"),                         //'class' of control to create
                           TEXT("Wait"),            //the control caption
                           WS_CHILD|WS_VISIBLE|BS_DEFPUSHBUTTON,   //control style: how it looks
                           120,                                     //control position: left
                           10,                                     //control position: top
                           100,                                    //control width
                           20,                                     //control height
                           hwnd,                                   //parent window handle
                           (HMENU)IDC_SERVER,                                   //control's ID
                           g_hInst,                                //application instance
                           NULL);  
                           
          break;
          case WM_WSAASYNC:
          // what word?
            
            switch(WSAGETSELECTEVENT(lParam))
            {
              case FD_ACCEPT:
                MessageBox(NULL,"Connection request received","Alert!",MB_OK); //this comes up
                // check for an error
                if (WSAGETSELECTERROR(lParam))
                  return(FALSE);
                // process message
                try
                {
                netwkobj.Accept();
                }
                catch (const NetErr& error)
                {
                  MessageBox(NULL,error.what(),"Network Error",MB_OK|MB_ICONEXCLAMATION);
                }
                return(0);
              break;
              case FD_READ:
               //receiving data
              break;
              case FD_WRITE:
              //..
              break;
              case FD_CONNECT:
              //server got our connect message
                MessageBox(NULL,"Connect request accepted","Alert!",MB_OK); // this never comes up
              break;
              case FD_CLOSE:
              //connection closed
                PostQuitMessage(0); //just quit for now...i guess
              break;
            }
            
          break; 
          case WM_COMMAND:
            switch(LOWORD(wParam))
            {
              case IDC_CONNECT: //button pressed: try to connect to a server
                try
                {
                  netwkobj.Init(hwnd,false); 
                  netwkobj.Connect("192.168.2.15");
                }
                catch (const NetErr& error)
                {
                  MessageBox(NULL,error.what(),"Network Error!",MB_OK|MB_ICONEXCLAMATION);
                }
                //MessageBox(NULL,"Connected","OK",MB_OK);
              break;
              case IDC_SERVER:
                try
                {
                  netwkobj.Init(hwnd,true); //move this to when we try to join or host a game in a menu
                }
                catch (const NetErr& error)
                {
                  MessageBox(NULL,error.what(),"Network Error!",MB_OK|MB_ICONEXCLAMATION);
                }
            //    MessageBox(NULL,"Listening...","OK",MB_OK);
              break;
            }
          break;    
          case WM_DESTROY:
            PostQuitMessage (0);       /* send a WM_QUIT to the message queue */
          break;
          default:                      /* for messages that we don't deal with */
            return DefWindowProc (hwnd, message, wParam, lParam);
        }
    
        return 0;
    }
    Member functions:
    Code:
    //network class member fcns
    Network::Network()
    {
    hSocket = INVALID_SOCKET;
    numclients=0;
    
    }
    
    void Network::Init(HWND hwnd, bool isserver) 
    {
    init = true;
    WSADATA wsaData;
    if (WSAStartup(MAKEWORD(REQ_WINSOCK_VER,0), &wsaData)==0) //start winsock
    {
    // Check if major version is at least REQ_WINSOCK_VER
      if (LOBYTE(wsaData.wVersion) < REQ_WINSOCK_VER)
      {
        throw NetErr("Required Winsock Version not met!");
      }
    }  
    else
      throw NetErr("Error starting Winsock!");
    // create and test the socket
    hSocket = socket(AF_INET, SOCK_STREAM, 0);
    if (hSocket == INVALID_SOCKET)
      throw NetErr("INVALID_SOCKET");
    // make the socket asynchronous and notify of read, write, connect and close events
    // this is the client socket
    if (!isserver)
    {
    WSAAsyncSelect(hSocket, hwnd, WM_WSAASYNC, FD_WRITE | FD_CONNECT |
                                            FD_READ | FD_CLOSE); //set up asynchronous sockets
                                //request WRITE, READ, CONNECT, and CLOSE messages be sent
    server=false;
    }
    // make the socket asynchronous and notify of read, write, accept and close events
    // this is the server socket
    else
    {
    //is this the right order? (set to listen before call to WSAAsyncSelect()?
    
    sockaddr_in    sockAddr = {0};
    SetServerSockAddr(&sockAddr, SERVER_PORT);
    if (bind(hSocket, reinterpret_cast<sockaddr*>(&sockAddr), sizeof(sockAddr))!=0) 
      throw NetErr("Could not bind socket.");
    if (listen(hSocket, SOMAXCONN)!=0) //set socket to listen for incoming data
      throw NetErr("Could not put socket into listening mode.");
    
    WSAAsyncSelect(hSocket, hwnd, WM_WSAASYNC, FD_READ | FD_WRITE |
                                            FD_ACCEPT | FD_CLOSE); //again, async sockets
    
    
      
                                            
    server=true;
    }
    
    }
    
    void Network::Connect(const char* servIp)
    {
    if (!init)
      throw NetErr("Network not initialized!");
    sockaddr_in    sockAddr = {0};
    FillSockAddrDot(&sockAddr, servIp, SERVER_PORT);
    
    if ((hSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET)
      throw NetErr("Could not create socket.");
            
            // Connect to server
    if (connect(hSocket, reinterpret_cast<sockaddr*>(&sockAddr), sizeof(sockAddr))!=0)
      throw NetErr("Could not connect.");
    
    
    }
    
    void Network::Accept()
    {
    if (!init)
      throw NetErr("Network not initialized!");
      int clientSockSize = sizeof(client_addr);
      client_sock[0] = accept(hSocket,reinterpret_cast<sockaddr*>(&client_addr), &clientSockSize);
    //I never get an exception thrown, and if I put a messagebox here
    //it never comes up
      if (client_sock[numclients]==INVALID_SOCKET)
        throw NetErr("Could not accept incoming connection");
      numclients++;  
    }
    As I said, it seems to be working up to that point (I get a "could not connect" exception if I try to connect without setting another instance to wait, and if I set one to wait, when I click "connect" the other instance receives an FD_ACCEPT message)

    Hopefully I'm just doing something stupid, since this is my first try with asynchronous sockets.

    Edit: Boy, I feel stupid. I guess WSAGETSELECTERROR is telling me there's an error. Somehow I just glanced over that line. Should've put some kind of notification there. Now I just gotta figure out what the error means...

    Edit2: MSDN doesn't have any error codes listed for the FD_ACCEPT message, and it returns error code 8...If I just continue like there's no problem, accept finished like there isn't a problem, but my client doesn't receive an FD_CONNECT message.

    Edit3: Yes, another edit. Ok so now I realize that there aren't actually any error (stupid tutorial told me wrong) But I still don't receive a FD_CONNECT message...I think I'll take a break on this now...
    Last edited by JaWiB; 01-27-2005 at 10:07 PM.
    "Think not but that I know these things; or think
    I know them not: not therefore am I short
    Of knowing what I ought."
    -John Milton, Paradise Regained (1671)

    "Work hard and it might happen."
    -XSquared

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 12
    Last Post: 02-10-2009, 02:14 PM
  2. non-MFC DLL with MFC app question.
    By Kempelen in forum Windows Programming
    Replies: 10
    Last Post: 08-20-2008, 07:11 AM
  3. Bluetooth client/server app
    By wierdbeard65 in forum Networking/Device Communication
    Replies: 0
    Last Post: 06-12-2007, 06:05 AM
  4. best program to start
    By gooddevil in forum Networking/Device Communication
    Replies: 4
    Last Post: 05-28-2004, 05:56 PM
  5. pasword app
    By GanglyLamb in forum C Programming
    Replies: 2
    Last Post: 06-07-2003, 10:28 AM