CAsyncSocket: Als Client verbinden sobald der Host vorhanden ist.
-
Hat keiner eine Idee?
-
Dein CObject-Zeiger is an der Stelle NULL, also das existiert noch nicht oder nicht mehr oder wie auch immer.
-
Aber unmittelbar davor erstelle ich das Objekt doch....
Und der selbe Code funktioniert ja auch wenn ich ihn im Main Thread ausführe. Das Problem tritt nur auf wenn ich dies in einem weiterm Thread mache
-
So wie Martin Richter schon geschrieben hat, ich zitiere:
Viele MFC Objekte sind threadafin. D.h. Du kannst Sie nur in dem Thread benutzen, der sie erzeugt.
Du erzeugst global (im ertsen Thread) CMySocket Objekte. Diese gehören also diesem "Main-Thread". Dann bentzt Du diese aber in einem anderen Thread.
Das muss knallen.
Erzeuge Deine CMySocket Objekte in dem Workerthread!
Versuch mal deine CMySocket Objete nicht im Thread anzulegen, sondern beispielsweise in OnInitDialog, bevor du den Thread startest.
-
Source2702 schrieb:
Versuch mal deine CMySocket Objete nicht im Thread anzulegen, sondern beispielsweise in OnInitDialog, bevor du den Thread startest.
Die Objekte existieren doch schon, da sie Membervariablen des Dialogs sind, wenn ich das richtig verstanden hab. Du meinst sicher das das Create außerhalb des Threads passieren sollte... Das würde ich auch als nächstes testen. Damit läuft nur noch das while() im Thread.
-
Du erzeugst sie mit new im Thread, wie ich gesehen habe.
Erzeuge sie (mit oder ohne new) im Hauptthread. Sollte das Problem lösen.
-
Source2702 schrieb:
Du erzeugst sie mit new im Thread, wie ich gesehen habe.
Erzeuge sie (mit oder ohne new) im Hauptthread. Sollte das Problem lösen.Nö, denke ich nicht, wenn ich folgenden Code sehe:
CMySocket CSocket02Dlg::m_sListenSocket; CMySocket CSocket02Dlg::m_sConnectSocket; unsigned int CSocket02Dlg::TrySocketConnect(LPVOID pParam) { m_sConnectSocket.SetParent((CDialog *)pParam); m_sListenSocket.SetParent((CDialog *)pParam); //--- Versuchen als Client Verbindung //--- zu einem Server zu bekommen if(!m_sListenSocket.Create()) RETAILMSG(1,(_T("m_sListenSocket.Create: %d\n\r"), GetLastError())); while(!m_sListenSocket.Connect(_T("172.31.255.1"), 6000)) { RETAILMSG(1,(_T("Try to Connect\n\r"))); Sleep(1000); } RETAILMSG(1,(_T("Connected now!\n\r"))); return 0; } BOOL CSocket02Dlg::OnInitDialog() { CDialog::OnInitDialog(); AfxBeginThread(TrySocketConnect, (LPVOID)this); ... ... }
Die Konstruktion erfolgt eindeutig außerhalb des Threads. Aber der Ansatz, dass der Create-Aufruf außerhalb des Threads erfolgen sollte, müsste mal getestet werden.
-
Doch, doch. In seiner letzten Implementierung, die er hier gepostet hat, war es mit new drin. Auf diese hab ich mich bezogen.
Ist aber egal, es hängt höchstwahrscheinlich am Create.
-
So, ich bin wieder einen Schritt weiter. Der Tipp mit dem Create war goldrichtig. Das Create gehört in den Hauptthread, dann geht es.
Vielen Dank
Nur einen Sache funktioniert noch nicht.
Wenn die Hostanwendung nun wieder geschlossen wird, soll meine Anwendung wieder pollen und sich wieder verbinden, sobald die Hostanwendung wieder da ist.
So habe ich es versucht:
// CMySocket-Memberfunktionen void CMySocket::SetParent(CDialog * pWnd) { m_pWnd = pWnd; } void CMySocket::OnClose(int nErrorCode) { #ifdef _WIN32_WCE if (INVALID_SOCKET != m_hSocket) { RETAILMSG(1, (_T("AsyncSelect(0);\n"))); AsyncSelect(0); // switch of eventhandling } #endif RETAILMSG(1, (_T("OnClose:\n"))); CAsyncSocket::OnClose(nErrorCode); if(nErrorCode == 0) ((CSocket02Dlg*)m_pWnd)->OnClose(); }
// Socket02Dlg.cpp : Implementierungsdatei // CMySocket *CSocket02Dlg::m_psListenSocket; CMySocket *CSocket02Dlg::m_psConnectSocket; unsigned int CSocket02Dlg::TrySocketConnect(LPVOID pParam) { while(!m_psListenSocket->Connect(_T("172.31.255.1"), 6000)) { if(GetLastError() == WSAEISCONN /* (10056) Socket is already connected. */) { RETAILMSG(1,(_T("GetLastError() == WSAEISCONN -> break\n"))); break; } RETAILMSG(1,(_T("Try to Connect - Error Code: %d\n"),GetLastError())); Sleep(1000); } RETAILMSG(1,(_T("Connected now!\n"))); return 0; } BOOL CSocket02Dlg::OnInitDialog() { CDialog::OnInitDialog(); m_psConnectSocket = new CMySocket; m_psListenSocket = new CMySocket; m_psConnectSocket->SetParent(this); m_psListenSocket->SetParent(this); //--- Versuchen als Client Verbindung //--- zu einem Server zu bekommen if(!m_psListenSocket->Create()) RETAILMSG(1,(_T("m_psListenSocket->Create: %d\n\r"), GetLastError())); AfxBeginThread(TrySocketConnect, (LPVOID)this); } void CSocket02Dlg::OnClose() { RETAILMSG(1, (_T("CSocket02Dlg::OnClose: \r\n"))); m_psConnectSocket->Close(); m_psListenSocket->Close(); AfxBeginThread(TrySocketConnect, (LPVOID)this); }
Wird nun also die Verbindung Seitens der Hostanwendung geschlossen, wird das OnClose Event aufgerufen. Dort rufe ich die OnClose Funktion meiner Dialogklasse auf. In dieser starte ich wieder den 'PollThread'.
Nur wird dann keine Verbindung aufgebaut. Connect kommt immer mit dem ReturnValue WSAENOTSOCK (10038) Socket operation on non-socket. zurück.
Wo liegt hier nun wieder das Problem?
-
*push*
-
Hat keiner eine Idee?
-
Bin mir nicht ganz sicher, aber du kannst das ja mal versuchen die beiden Close der Sockets wegzulassen, also die in der OnClose deines Dialoges, nicht das der da rum spinnt weil die beiden ja schon geschlossen sind, hatte da was bei MS gelesen, aber ob das auf deinen Fall zutrifft
http://support.microsoft.com/kb/155738/de
is aber wie gesagt nur ne dumme idee ob dich das weiter bringt, weis ich nicht