[C++] Warum? Probleme mit MainFrame und CSocket

sisela

Erfahrenes Mitglied
Hallo,

folgendes funktioniert einwandfrei:
Code:
SockServer.Create(21124,1,"127.0.0.1");
	
// listen on socket
if (!SockServer.Listen()) {
  showSocketError(SockServer, pMainFrame);
  goto CloseAll;
}

// wait for client
  if (!SockServer.Accept(SockReceiver)) {
    showSocketError(SockReceiver, pMainFrame);
    goto CloseAll;
}
Muss aber eine Membervariable von CSocket im MainFrame haben. Diese Funktion läuft als extra Thread und ich übergebe ihr nun nur den this Pointer von MainFrame. In der MainFrame Klasse habe ich nun die CSocket Membervariablen. Folgender Code geht aber nicht mehr, wird zwar compiliert aber wirft ständig eine Exception in der wincore.cpp, die wiederum sagt, dass der Socket blockiert ist. (WSAWOULDBLOCK) oder so

Hier mein geänderter nicht funktionierender Code
Code:
// wird schon im MainFrame created
//SockServer.Create(21124,1,"127.0.0.1");
	
// listen on socket
  if (!pMainFrame->m_SockServer.Listen()) {
    showSocketError(pMainFrame->m_SockServer, pMainFrame);
    goto CloseAll;
}

// Hier kommt der Fehler immer im Sekundenrhytmus
if (!pMainFrame->m_SockServer.Accept(SockReceiver)) {
  showSocketError(SockReceiver, pMainFrame);
  goto CloseAll;
}

Warum ist das so, kann ich nicht auf die Membervariablen zugreifen, wegen Thread oder verstehe ich irgendetwas falsch.

Wäre schön, wenn mir jemand helfen könnte
 
Wird der Zeiger auch richtig dereferenziert?
Probiers einfach mal ohne das Accept, ob dann auch Errors kommen.
Kommt denn eine NullPointerException?

Ansonsten gibt es bei Sockets noch eine andere Lösung, die nennt sich nonblocking-mode, die stellt man an, wenn das Programm nicht auf Accepts warten soll.
 
Zuletzt bearbeitet:
Hi,
wie kann ich denn den Zeiger richtig dereferenzieren?
Also hab mal accept weggelassen und da kommen auch ständig Fehler in der wincore.cpp aber diemal an verschiedenen Stellen.

Wenn ich überhaupt nicht auf pMainFrame zugreife ist alles ok.

Wie kann ich abhilfe schaffen?

PS: Non-Blocking kommt nicht in Frage!
 
Dereferenzieren ist dies hier:
pMainFrame->

Das heisst ja eigentlich (*pMainFrame).

Ich wollte jetzt nur wissen, ob pMainFrame ein korrekter Pointer auf etwas ist.
 
a) Hast du geprüft, ob Create wirklich vor Listen aufgerufen wird? Das WSAWOULDBLOCK kommt, wenn der Socket während dem Erzeugen (bzw. danach) nicht auf Non-Blocking umgestellt wird.

b) Mit non-blocking Sockets und Threads höllisch aufpassen. Wenn da ein HWND für die Socket-Nachrichten intern verwendet wird, muss sichergestellt werden, dass der Thread, wo das HWND erzeugt wird, auch eine Message-Pump hat (Bin selbst drauf reingefallen).
 
Hi,
@Thomas Kuse
Wird der Zeiger auch richtig dereferenziert?
Ja, CMainFrame *pMainFrame.

@Endurion
Hast du geprüft, ob Create wirklich vor Listen aufgerufen wird?
a) Ja Create wird vor Listenig aufgerufen.
Mit non-blocking Sockets und Threads höllisch aufpassen. Wenn da ein HWND für die Socket-Nachrichten intern verwendet wird, muss sichergestellt werden, dass der Thread, wo das HWND erzeugt wird, auch eine Message-Pump hat (Bin selbst drauf reingefallen).
b) genau das ist das Problem, er landet in der wincore.cpp bei einem Fehler mit fehlender Message Pump. Was ist MessagePump überhaupt und wie hast du das Problem gelöst?

@all
ich poste später nochmal code aber im Moment will ich das ganze nochmal umstrukturieren, vielleicht gehe ich von dem Thread ab und reagiere eher auf OnConnect, OnAccept und OnReceive.
Aber danke erstmal, für weitere Hinweise wäre ich natürlich dankbar.
Also bis dann...
 
Eine MessagePump ist das, was MFC ganz toll versteckt hält. In einem normalen Win32 Programm hast du die Schleife selbst gebaut: GetMessage/PeekMessage -> TranslateMessage -> DispatchMessage.

Eine MessagePump funktioniert immer nur für einen Thread. Es gibt zwar auch MFC-Threads, die eine eigene MessagePump haben, die sind aber nicht so praktikabel.

Du kannst in deiner Thread-Funktion einfach eine MessagePump hinzufügen (es muss natürlich der Thread sein, der das Fenster erzeugt bzw. Create aufruft). Da die Funktion vermutlich eine Art Endlosschleife hat, einfach da drin sowas einsetzen:

Code:
while ( !bAbbruchBedingung )
{
  MSG    msg;

  // Messagepump für den Sockethandler
  if ( PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE ) )
  {
    GetMessage( &msg, NULL, 0, 0 );
    TranslateMessage( &msg );
    DispatchMessage( &msg );
  }
  else
  {
    // normaler Thread-Ablauf, hier keine zu fetten Sachen am Stück machen, evtl. ein Sleep einsetzen
    Sleep( 20 );
  }
}
 
@Endurion
Hi,
vielleicht ist das auch das ganze Problem. Denn ich erzeuge den Socket in einem anderen Thread. Die MessagePump wird wiederum auch in einem anderen Thread aufgerufen und verursacht dort den Fehler. Das kann dann vielleicht das Problem sein.
Aber wie gesagt ich schreibe das Programm im Moment sowieso um.
mfg
Christian ;)
 
Hallo Leute,
habe ganz vergessen, dass ich ja noch die Lösung posten wollte. Also das Problem liegt ja einfach darin, dass die Receive Funktion blockiert, wenn der Socket nichts liefert. Das mach dann wiederum Probleme.
Ich habe jetzt einfach eine Klasse von CSocket abgeleitet in der ich die OnReceive Funktion überschrieben habe. In dieser Klasse ist auch ein Zeiger auf den MainFrame und daher auch voller Zugriff auf diesen. Nun funktioniert alles bestens.
Ich kann an dieser Stelle allen anderen die Probleme mit Sockets haben empfehlen, sich das msdn Beispiel Chatter und ChatServer anzusehen.

ok bis dann
Gruß @all
Christian
 

Neue Beiträge

Zurück