nochmal wxSockets



  • Hallo,
    habe ein Problem mit den wxSockets...
    Die Verbindung zwischen beiden Programmen funktioniert und es wird auch mein Teststring übertragen. nur wird die Socketverbindung nach der übertragung beendet, was Sie eigentlich nicht soll!
    Hier mal relevante Code auszüge der
    sendende Klasse:

    #include "AuslastungFrm.h"
    
    ////Event Table Start
    BEGIN_EVENT_TABLE(AuslastungFrm,wxFrame)
    	////Manual Code Start
    	EVT_PAINT  (AuslastungFrm::OnPaint)
    	EVT_TIMER  (TIMER_ID, AuslastungFrm::OnTimer)
    	EVT_SOCKET(SOCKET_ID, AuslastungFrm::OnSocketEvent)
    	////Manual Code End
    
    	EVT_CLOSE(AuslastungFrm::AuslastungFrmClose)
    END_EVENT_TABLE()
    ////Event Table End
    
    AuslastungFrm::AuslastungFrm(wxWindow *parent, wxWindowID id, const wxString &title, const wxPoint &position, const wxSize& size, long style)
    : wxFrame(parent, id, title, position, size, style)
    
    {          
      CreateGUIControls();
    
      #if wxUSE_STATUSBAR
      // Status bar
      CreateStatusBar(2);
      #endif // wxUSE_STATUSBAR
    
      // Create the socket
      m_sock = new wxSocketClient();
      m_sock->SetEventHandler(*this, SOCKET_ID);
      m_sock->SetNotify(wxSOCKET_CONNECTION_FLAG |
                        wxSOCKET_INPUT_FLAG |
                        wxSOCKET_LOST_FLAG);
      m_sock->Notify(true);
      m_busy = false;
      UpdateStatusBar();
      wxIPV4address addr;
      addr.Hostname("127.0.0.1");
      addr.Service(3000);
      SetStatusText("Trying to connect (timeout = 10 sec) ...", 1);
      m_sock->Connect(addr, false);
      m_sock->WaitOnConnect(10);
    
      if (m_sock->IsConnected()){   
         SetStatusText("Succeeded ! Connection established", 1);
         }
      else
      {
        m_sock->Close();
        SetStatusText("Failed ! Unable to connect", 1);
        wxMessageBox(_("Can't connect to the specified host"), _("Alert !"));
      }
    
      UpdateStatusBar();
      Send();// sendet einen Teststring
    
    }
    void AuslastungFrm::Send(){
    
      const wxChar *c;
      size_t len;
      wxString bla;
    
      bla="test";
      WxStaticText2->SetLabel(bla);
      c=bla.c_str();
      len  = (wxStrlen(c) + 1) * sizeof(wxChar);
      m_sock->WriteMsg(c, len);
      if (m_sock->Error()){
         switch(m_sock->LastError())
         {
         case wxSOCKET_NOERROR      : WxMessageDialog_Socket_fehler =  new wxMessageDialog(NULL, wxT("NOERROR"), wxT("Socket Error")); WxMessageDialog_Socket_fehler->ShowModal(); break;
         case wxSOCKET_INVOP        : WxMessageDialog_Socket_fehler =  new wxMessageDialog(NULL, wxT("INVOP"), wxT("Socket Error")); WxMessageDialog_Socket_fehler->ShowModal(); break;
         case wxSOCKET_IOERR        : WxMessageDialog_Socket_fehler =  new wxMessageDialog(NULL, wxT("IOERR"), wxT("Socket Error")); WxMessageDialog_Socket_fehler->ShowModal(); break;
         case wxSOCKET_INVADDR      : WxMessageDialog_Socket_fehler =  new wxMessageDialog(NULL, wxT("INVADDR"), wxT("Socket Error")); WxMessageDialog_Socket_fehler->ShowModal(); break;
         case wxSOCKET_INVSOCK      : WxMessageDialog_Socket_fehler =  new wxMessageDialog(NULL, wxT("INVSOCK"), wxT("Socket Error")); WxMessageDialog_Socket_fehler->ShowModal(); break;
         case wxSOCKET_NOHOST       : WxMessageDialog_Socket_fehler =  new wxMessageDialog(NULL, wxT("NOHOST"), wxT("Socket Error")); WxMessageDialog_Socket_fehler->ShowModal(); break;
         case wxSOCKET_INVPORT      : WxMessageDialog_Socket_fehler =  new wxMessageDialog(NULL, wxT("INVPORT"), wxT("Socket Error")); WxMessageDialog_Socket_fehler->ShowModal(); break;
         case wxSOCKET_WOULDBLOCK   : WxMessageDialog_Socket_fehler =  new wxMessageDialog(NULL, wxT("WOULDBLOCK"), wxT("Socket Error")); WxMessageDialog_Socket_fehler->ShowModal(); break;
         case wxSOCKET_TIMEDOUT     : WxMessageDialog_Socket_fehler =  new wxMessageDialog(NULL, wxT("TIMEDOUT"), wxT("Socket Error")); WxMessageDialog_Socket_fehler->ShowModal(); break;
         case wxSOCKET_MEMERR       : WxMessageDialog_Socket_fehler =  new wxMessageDialog(NULL, wxT("MEMERR"), wxT("Socket Error")); WxMessageDialog_Socket_fehler->ShowModal(); break;               
         case wxSOCKET_DUMMY       : WxMessageDialog_Socket_fehler =  new wxMessageDialog(NULL, wxT("DUMMY"), wxT("Socket Error")); WxMessageDialog_Socket_fehler->ShowModal(); break;
         }                  
      }
    }
    
    void AuslastungFrm::OnSocketEvent(wxSocketEvent& event)
    {
      wxString s = _("OnSocketEvent: ");
    
      switch(event.GetSocketEvent())
      {
        case wxSOCKET_INPUT      : s.Append(_("wxSOCKET_INPUT\n")); break;
        case wxSOCKET_LOST       : s.Append(_("wxSOCKET_LOST\n")); break;
        case wxSOCKET_CONNECTION : s.Append(_("wxSOCKET_CONNECTION\n")); break;
        default                  : s.Append(_("Unexpected event !\n")); break;
      }
    
      SetStatusText(s, 1);
      UpdateStatusBar();
    }
    
    void AuslastungFrm::UpdateStatusBar()
    {
      wxString s;
    
      if (!m_sock->IsConnected())
      {
        s.Printf(_("Not connected"));
      }
      else
      {
        wxIPV4address addr;
    
        m_sock->GetPeer(addr);
        s.Printf(_("%s : %d"), (addr.Hostname()).c_str(), addr.Service());
      }
    
    #if wxUSE_STATUSBAR
      SetStatusText(s, 0);
    #endif // wxUSE_STATUSBAR
    
    }
    

    Wenn ich nichts "explizit" sende, also Send() auskommentiere, verhält sich alles so wie es soll. Die Socketverbindung wird erst beendet wenn ich eins der beiden Programme schließe!
    Und hier noch die Serverseite:

    BEGIN_EVENT_TABLE(GUI_ServerFrm,wxFrame)
    	////Manual Code Start
    	EVT_TIMER  (TIMER_ID, GUI_ServerFrm::OnTimer)
    	EVT_TIMER  (TIMER_ID2, GUI_ServerFrm::OnTimer2)
    	EVT_TIMER  (TIMER_ID3, GUI_ServerFrm::OnTimer3)
    	EVT_SOCKET(SERVER_ID,  GUI_ServerFrm::OnServerEvent)
    	EVT_SOCKET(SOCKET_ID,  GUI_ServerFrm::OnSocketEvent)
    	////Manual Code End
    
    	EVT_CLOSE(GUI_ServerFrm::GUI_ServerFrmClose)
    	EVT_BUTTON(ID_START_ACCOUNTING,GUI_ServerFrm::start_accountingClick)
    	EVT_BUTTON(ID_START_REPORT,GUI_ServerFrm::Start_reportClick)
    	EVT_BUTTON(ID_WXBUTTON3,GUI_ServerFrm::create_userClick)
    	EVT_BUTTON(ID_WXBUTTON2,GUI_ServerFrm::stop_serverClick)
    	EVT_BUTTON(ID_WXBUTTON1,GUI_ServerFrm::start_serverClick)
    END_EVENT_TABLE()
    ////Event Table End
    
    GUI_ServerFrm::GUI_ServerFrm(wxWindow *parent, wxWindowID id, const wxString &title, const wxPoint &position, const wxSize& size, long style)
    : wxFrame(parent, id, title, position, size, style) {
    
        CreateGUIControls();
    
       #if wxUSE_STATUSBAR
         CreateStatusBar(2);
       #endif // wxUSE_STATUSBAR
    
      wxIPV4address addr;
      addr.Service(3000);
      m_server = new wxSocketServer(addr);
    
      if (! m_server->Ok())
      {
        SetStatusText("Could not listen at the specified port !", 1);
        return;
      }
      else
      {
        SetStatusText("Server listening.", 1);
      }
      m_server->SetEventHandler(*this, SERVER_ID);
      m_server->SetNotify(wxSOCKET_CONNECTION_FLAG);
      m_server->Notify(true);
      m_busy = false;
      m_numClients = 0;
      UpdateStatusBar();
    
    }
    
    void GUI_ServerFrm::OnServerEvent(wxSocketEvent& event)
    {
      wxString s = _("OnServerEvent: ");
      wxSocketBase *sock;
    
      switch(event.GetSocketEvent())
      {
        case wxSOCKET_CONNECTION : s.Append(_("wxSOCKET_CONNECTION\n")); break;
        default                  : s.Append(_("Unexpected event !\n")); break;
      }
    
      SetStatusText(s, 1);
      sock = m_server->Accept(false);
    
      if (sock)
      {
        SetStatusText("New client connection accepted", 1);
      }
      else
      {
        SetStatusText("Error: couldn't accept a new connection", 1);
        return;
      }
    
      sock->SetEventHandler(*this, SOCKET_ID);
      sock->SetNotify(wxSOCKET_INPUT_FLAG | wxSOCKET_LOST_FLAG);
      sock->Notify(true);
    
      m_numClients++;
      UpdateStatusBar();
    }
    
    void GUI_ServerFrm::OnSocketEvent(wxSocketEvent& event)
    {
      wxString s = _("OnSocketEvent: ");
      wxSocketBase *sock = event.GetSocket();
    
      switch(event.GetSocketEvent())
      {
        case wxSOCKET_INPUT : s.Append(_("wxSOCKET_INPUT\n")); break;
        case wxSOCKET_LOST  : s.Append(_("wxSOCKET_LOST\n")); break;
        default             : s.Append(_("Unexpected event !\n")); break;
      }
    
      SetStatusText(s, 1);
      switch(event.GetSocketEvent())
      {
        case wxSOCKET_INPUT:
        {
          #define MAX_MSG_SIZE 10000
          wxChar *buf = new wxChar[MAX_MSG_SIZE];
          wxString data;
          sock->SetNotify(wxSOCKET_LOST_FLAG);
          sock->ReadMsg(buf, MAX_MSG_SIZE * sizeof(wxChar)).LastCount();
          data=buf;
          WxStaticText20->SetLabel(data);
    
        }
        case wxSOCKET_LOST:
        {
          m_numClients--;
          SetStatusText("Deleting socket.", 1);
          sock->Destroy();
          break;
        }
        default: ;
      }
      UpdateStatusBar();
    }
    
    void GUI_ServerFrm::UpdateStatusBar()
    {
    #if wxUSE_STATUSBAR
      wxString s;
      s.Printf(_("%d clients connected"), m_numClients);
      SetStatusText(s, 0);
    #endif // wxUSE_STATUSBAR
    }
    

    Ich weiß, ziemlich viel Code, aber ich finde den Fehler einfach nicht...


  • Mod

    Lösche doch bitte den nicht relevanten code...

    Ansonsten, Firewall etc. kann als Fehlerquelle ausgeschlossen werden?



  • Ich habe ja leider keine Ahnung was nicht relevant sein könnte, deshalb hab ich alles gepostet was mit den Sockets zu tun hat...
    Und ja, externe Effekte kann ich ausschließen!

    Muss ich eventuell nach dem senden wieder bestimmte Flags oder sowas setzen damit die Verbindung bestehen bleibt. Wie gesagt, das Senden funktioniert nur das danach halt die verbindung getrennt wird, was si nicht soll!

    Danke & Gruß


  • Mod

    Kann jetzt auf die Schnelle nix finden, evtl. probierst du mal aus ob das Senden ausserhalb des Konstruktors klappt.
    Und das Socket Beispiel unter %wxDir%/samples/sockets solltest du dir mal anschauen.



  • Aus dem Beispiel hab ich ja den meisten Quellcode, bin aber gerade dabei es nochmal durchzuschauen, ob ich was finde woran es liegen könnte.
    WEnn dir doch noch was einfällt oder du was findest und dann nochmal bescheid geben könntest wäre ich dir sehr dankbar. Sollte ich das Problem gelöst haben sag ich natürlich auch bescheid...


  • Mod

    wäre nur noch, ob du wxSocketBase::Initialize() aufgerufen hast, und welche wxVersion du verwendest...



  • Denke habs gefunden 😃
    meine Vermutung mit den Flags war wohl richtig.
    Habe auf der Serverseite nach dem Empfangen dashier

    sock->SetNotify(wxSOCKET_LOST_FLAG | wxSOCKET_INPUT_FLAG);
    sock->Notify(true);
    

    eingesetzt und jetzt bleibt die Verbindung bestehen!


Anmelden zum Antworten