Socket blockiert
-
Hallo
ich schreibe gerade an einem Programm, bei dem ich eine Testnachricht an einen Server sende.
Problem: Die erste Nachricht geht noch. Dann schließe ich den Socket der die Nachricht geschickt hat (macht wenig Sinn aber es is zum Testen), ich bekomm beim Server die Nachricht das der Socket den ich bei WM_ACCEPT übergeben hab geschlossen werden will, schließe auch den. Aber trotzdem bleibt bei netstat -a der Socket der die Nachricht geschickt hat bestehen mit dem Zustand WARTEND. Ziemlich ärgerlich, weil ich will mich zu einem anderen Server verbinden, aber da der andere noch WARTEND ist kann ich natürlich den neuen Socket nicht mehr erstellen (Port schon belegt).
Kann mir jemand sagen wie ich den wartenden Socket beenden kann ?
-
ohne code ist die einzige diagnose die ich abgeben kann:
wird schon so passen, sonst würds net so sein
-
Naja, den Code kann ich ja mal posten, aber ob das soviel bringt:
Ansehen sollte man die Funktionen SendTest(CString IP) (Damit teste ich ob ich eine Verbindung zum Server aufbauen kann) und MsgSocketFunc (da die Zeile mit case WM_SCK_CLOSE, da schließ ich den Socket von WM_SCK_ACCEPT)Vielleicht kann mir auch jemand sagen, wie ich den Timeout für eine Verbindung setzen kann. Vielleicht bringt das etwas.
Irgendwie bleibt der Socket auch noch WARTEND wenn ich das Programm beendet hab, obwohl er eigentlich mit delete schon im Nirvana sein sollte// REMConnection.cpp: Implementierung der Klasse REMConnection. // ////////////////////////////////////////////////////////////////////// /*Hinweis: Diese Klasse funktioniert mit CXSocket CXSocket ist nur eine Ableitung von CSocket nur dass CXSocket eine globale Funktion aufruft wenn eine Nachricht ankommt*/ #include "stdafx.h" #include "stdafx.h" #include "REMConnection.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif ////////////////////////////// //auf ein paar umwegen die Klassenfunktion aufrufen -> Es darf nur ein REMConnection Objekt existieren: CREMConnection *pTheOnlyREMCon=NULL; void SetOnlyREMConnection(CREMConnection *REMCon) { if(pTheOnlyREMCon!=NULL) //Oh,oh es existiert schon eine!!!! { TRACE0("Es darf nur ein REMConnection-Objekt im Programm geben!!!!"); ASSERT(FALSE); //Tja } ASSERT(REMCon!=NULL); //das is nun wirklich dumm.... pTheOnlyREMCon=REMCon; } void glblXSockMsgFunc(int sock_msg,int error,int ID,int lParam,int wParam) { ASSERT(pTheOnlyREMCon!=NULL); //ja das sollt es nicht sein pTheOnlyREMCon->MsgSocketFunc(sock_msg,error,ID,lParam,wParam); } ////////////////////////////////////////////////////////////////////// // Konstruktion/Destruktion ////////////////////////////////////////////////////////////////////// CREMConnection::CREMConnection() { MyIP="0.0.0.0"; CountSockets=ActiveSockets=0; ppSockets=NULL; pServerSocket=NULL; pParentWnd=NULL; SetOnlyREMConnection(this); } CREMConnection::~CREMConnection() { DeleteSocketsPointer(); if(pServerSocket!=NULL) { pServerSocket->Close(); delete pServerSocket; } } //Diese Funktion bekommt alle Nachrichten von den Sockets die erstellt wurden void CREMConnection::MsgSocketFunc(int sock_msg,int error,int ID,int lParam,int wParam) { TRACE2("[CREMConnection]: Habe vom Socket %i eine Nachricht erhalten! Msg-Nummer: %i\n",ID,sock_msg); TRACE1("Nachricht: %s\n",CXSocketWM2String(sock_msg)); if(ID==-1) //Server spricht zu uns { TRACE0("[CREMConnection] Nachricht für Server angekommen!\n"); if(sock_msg==WM_SCK_ACCEPT) { CXSocket *pNewSocket=CreateNewSocket(); pNewSocket->m_State=SCK_CLIENT; if(pServerSocket->Accept(*pNewSocket)) TRACE1("[CREMConnection]: Eine Verbindung wurde über Socket mit ID %i aufgebaut!\n",pNewSocket->m_ID); else TRACE0("[CREMConnection]: Der Server konnte keine Verbindung aufbauen!!!!!\n"); } } else //Alle anderen behandeln { ASSERT(ID<CountSockets); CXSocket *pMsgSocket=ppSockets[ID]; //Deklaration aller Variablen in switch int n=0; //n zum zählen //case WM_SCK_RECEIVE: int rec_size=0; //größe von empfangener bytes char rec_buffer[1024]; int real_size=0; //Anzahl empfangener Bytes char *bytes=NULL; char *sav_buffer=NULL; char rem_msg; //end case WM_SCK_RECEIVE switch(sock_msg) { case WM_SCK_RECEIVE: do { rec_size=pMsgSocket->Receive(rec_buffer,sizeof(rec_buffer)); if(rec_size==0) break; //Abbruch! if(bytes!=NULL) //Abspeichern des Puffers { sav_buffer=new char[real_size]; memcpy(sav_buffer,bytes,real_size); delete [] bytes; bytes=new char[real_size+rec_size]; //Platz für die nächsten Bytes memcpy(bytes,sav_buffer,real_size); //Alte Bytes vom Buffer in den neuen }//Geschafft!!! else bytes=new char[rec_size]; memcpy(&bytes[real_size],rec_buffer,rec_size); //Neue Bytes anhängen real_size+=rec_size; } while(!(rec_size<sizeof(rec_buffer))); TRACE1("%i Bytes empfangen...\n",real_size); //Nachrichtenanalyse: rem_msg=bytes[0]; // Nachrichtennummer steht an erster Stelle switch(rem_msg) //nochmal switch.... oh gott { case REM_MSG_TEST: TRACE0("[CREMConnection]:Testnachricht erhalten!\n"); CallREMMsgArrived(0,0); delete [] bytes; break; default: TRACE0("Unbekannte REM-Nachricht erhalten!!!\n"); delete [] bytes; //ab in den Abfalleimer break; } // oje oje, das wird noch ne Arbeit break; //und raus aus switch!!!! //end WM_SCK_RECEIVE case WM_SCK_CLOSE: ppSockets[ID]->Close(); TRACE0("Socket geschlossen!\n"); break; default: TRACE0("Socketnachricht nicht behandelt!!!! (oder brake vergessen)\n"); break; } } } CXSocket* CREMConnection::CreateNewSocket() { CXSocket **ppSocketsBuffer; ppSocketsBuffer=new CXSocket*[CountSockets+1]; if(CountSockets>0) { memcpy(ppSocketsBuffer,ppSockets,CountSockets*sizeof(void*)); //Alle Zeiger in den Buffer kopieren delete [] ppSockets; //Zeiger-Array löschen } ppSocketsBuffer[CountSockets]=new CXSocket; //Neuer Socket ASSERT(ppSocketsBuffer[CountSockets]!=NULL); ppSocketsBuffer[CountSockets]->SetMsgSocketFunc(&glblXSockMsgFunc); CountSockets++; ppSockets=ppSocketsBuffer; //ppSockets zeigt jetzt auf den Buffer //So vom Speicher her alles erledigt, jetzt kommt REM ppSockets[CountSockets-1]->m_ID=CountSockets-1; //So bekommt jeder eine ID die seinem Platz im Array entspricht TRACE2("[CREMConnection::CreateNewSocket] Socket mit der Adresse 0x%X und der ID %i erstellt!\n",ppSockets[CountSockets-1],ppSockets[CountSockets-1]->m_ID); return ppSockets[CountSockets-1]; //letzten = neuer Socket zurückgeben } void CREMConnection::DeleteSocketsPointer() { if(CountSockets>0) { for(int n=0;n<CountSockets;n++) { ppSockets[n]->Close(); delete ppSockets[n]; } delete [] ppSockets; } } CXSocket* CREMConnection::GetSocket(int ID) { if(ID==-1) return pServerSocket; else ASSERT(ID>0); CXSocket* pSock=ppSockets[ID]; return pSock; } BOOL CREMConnection::CreateServer() //Erstellt einen Server-Socket. Dieser aktzeptiert Verbindungen und gibt diese an einen anderen Socket ab! { pServerSocket=new CXSocket; ASSERT(pServerSocket); if(!pServerSocket->Create(REM_PORT_SERVER)) { TRACE0("[CREMConnection::CreateServer()]: Erstellen fehlgeschlagen! Create gab FALSE zurück!\n"); return FALSE; } if(!pServerSocket->Listen()) { TRACE0("[CREMConnection::CreateServer()]: Erstellen fehlgeschlagen! Listen gab FALSE zurück!\n"); return FALSE; } pServerSocket->SetMsgSocketFunc(&glblXSockMsgFunc); pServerSocket->m_State=SCK_SERVER; pServerSocket->m_ID=-1; TRACE0("CREMConnection: Server erstellt!\n"); return TRUE; } BOOL CREMConnection::SendTest(CString IP) { CXSocket *pTestSocket=CreateNewSocket(); if(!pTestSocket->Create(REM_PORT_CLIENT)) { TRACE0("[CREMConnection::SendTest]: Erstellen des Test-Sockets fehlgeschlagen!\n"); TRACE1("Fehlernummer: %i\n",GetLastError()); return FALSE; } TRACE1("Test-Socket mit ID %i erstellt!\n",pTestSocket->m_ID); if(!pTestSocket->Connect(IP,REM_PORT_SERVER)) { TRACE0("[CREMConnection::SendTest]: Verbinden des Test-Sockets fehlgeschlagen!\n"); TRACE1("Fehlernummer: %i\n",GetLastError()); return FALSE; } char test[]={REM_MSG_TEST,'T','E','S','T','\0'}; if(pTestSocket->Send(test,sizeof(test))==-1) { TRACE0("[CREMConnection::SendTest]: Nachricht konnte nicht abgeschickt werden!\n"); return FALSE; } pTestSocket->Close(); return TRUE; } void CREMConnection::CallREMMsgArrived(int lParam,int wParam) { ASSERT(pParentWnd!=NULL); ASSERT(pParentWnd->m_hWnd!=NULL); pParentWnd->SendMessage(WM_REM_MSG,lParam,wParam); } void CREMConnection::SetParentWnd(CWnd *pWnd) { ASSERT(pWnd!=NULL); if(pWnd!=NULL) TRACE0("[CREMConnection::SetParentWnd]: ParentWnd geändert!\n"); pParentWnd=pWnd; }