Search code examples
csocketsconsolewxwidgets

wxWidgets: Client connects to the server, but the server does not recognize


I'm creating (at the time, to learn how) two applications console: a server and a client.

The client can connect to the server. If the server is not available, the application terminates with error. The server waits make a connection, on line socketServer->Accept(1);. When the client connects, the code continues.. The problem is that the "if" following (if (socketServer->IsConnected()) {) evaluates to false.

Full source

Client

#include <wx/wxprec.h>
#include <wx/cmdline.h>
#include <wx/socket.h>
#include <wx/app.h>
#ifndef WX_PRECOMP
#include <wx/wx.h>
#endif

static const wxCmdLineEntryDesc cmdLineDesc[] = {
    { wxCMD_LINE_SWITCH, "h", "help", "show this help message",
        wxCMD_LINE_VAL_NONE, wxCMD_LINE_OPTION_HELP },
    { wxCMD_LINE_OPTION, "ip", NULL, "set ip; the default values is 127.0.0.1", wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL },
    { wxCMD_LINE_OPTION, "p", "port", "set port; the default values is 3000", wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL },
    { wxCMD_LINE_NONE }
};

int main(int argc, char **argv) {
    // Startup
    wxApp::CheckBuildOptions(WX_BUILD_OPTIONS_SIGNATURE, "program");

    wxInitializer initializer;
    if (!initializer) {
        fprintf(stderr, "Failed to initialize the wxWidgets library, aborting.\n");
        return -1;
    }

    // Default variables
    wxString ip = "127.0.0.1";
    wxString port = "3000";

    // Parse
    wxCmdLineParser parser(cmdLineDesc, argc, argv);
    switch (parser.Parse()) {
        case -1:
            return 0;
            break;
        case 0:
            parser.Found("ip", &ip);
            parser.Found("p", &port);
            break;
        default:
            break;
    }

    // Socket
    wxPrintf("Creating socket...\n");
    wxSocketClient *socketClient = new wxSocketClient(wxSOCKET_NONE);

    wxPrintf("Addressing...\n");
    wxPrintf("Usando ip %s\n", ip);
    wxIPV4address addr;
    if (!addr.Hostname(ip)) {
        wxPrintf("Could not set hostname !\n");
        return 1;
    }
    wxPrintf("Usando porta %s\n", port);
    if (!addr.Service(port)) {
        wxPrintf("Could not set service !\n");
        return 1;
    }

    wxPrintf("Trying to make connection...\n");
    if (socketClient->Connect(addr, true)) {
        wxPrintf("Success\n");
    } else {
        wxPrintf("Error!\n");
        return 1;
    }

    // Tell the server which test we are running
    wxPrintf("Sending...\n");
    unsigned char c = 0xDE;
    socketClient->Write(&c, 1);

    // This test also is similar to the first one but it sends a
    // large buffer so that wxSocket is actually forced to split
    // it into pieces and take care of sending everything before
    // returning.

    socketClient->SetFlags(wxSOCKET_WAITALL);

    // Note that len is in kbytes here!
    const unsigned char len = 32;
    wxCharBuffer buf1(len * 1024);

    for (size_t i = 0; i < len * 1024; i++)
        buf1.data()[i] = (char) (i % 256);

    socketClient->Write(&len, 1);
    socketClient->Write(buf1, len * 1024);

    wxPrintf("End!\n");

    while (1) {

    }
    return 0;
}

Server

#include <wx/wxprec.h>
#include <wx/cmdline.h>
#include <wx/socket.h>
#include <wx/app.h>
#ifndef WX_PRECOMP
#include <wx/wx.h>
#endif

static const wxCmdLineEntryDesc cmdLineDesc[] = {
    { wxCMD_LINE_SWITCH, "h", "help", "show this help message",
        wxCMD_LINE_VAL_NONE, wxCMD_LINE_OPTION_HELP},
    { wxCMD_LINE_SWITCH, "d", "dummy", "a dummy switch"},
    // ... your other command line options here...

    { wxCMD_LINE_NONE}
};

int main(int argc, char **argv) {
    // Startup
    wxApp::CheckBuildOptions(WX_BUILD_OPTIONS_SIGNATURE, "program");

    wxInitializer initializer;
    if (!initializer) {
        fprintf(stderr, "Failed to initialize the wxWidgets library, aborting.\n");
        return -1;
    }

    // Creat socket
    wxPrintf("Criando socket...\n");
    wxSocketServer *socketServer;
    wxIPV4address addr;

    if (!addr.Hostname("127.0.0.1")) {
        wxPrintf("Could not set hostname !\n");
        return 1;
    }
    if (!addr.Service(3000)) {
        wxPrintf("Could not set service !\n");
        return 1;        
    }
    socketServer = new wxSocketServer(addr);
    if (!socketServer->IsOk())  {
        wxPrintf("Could not listen at the specified port !\n");
        return 1;
    }

    // Efetuar conexao
    wxPrintf("Waiting for connection...\n");
    socketServer->Accept(1);
    if (socketServer->IsConnected()) {
        wxPrintf("Success\n");
    } else {
        wxPrintf("Not connected\n");
    }

    while (1) {

    }

    return 0;
}

Solution

  • After hours studying and trying, I solved the problem.

    wxPrintf("Waiting for connection...\n");
    wxSocketBase socketTest;
    socketServer->AcceptWith(socketTest, true);
    if (socketTest.IsConnected()) {
        wxPrintf("Success\n");
    } else {
        wxPrintf("Not connected\n");
    }
    

    In the manual is written a detail that had not understood:

    Accepts an incoming connection request, and creates a new wxSocketBase object which represents the server-side of the connection.