Prev: deploying mfc-based ActiveX control (VC++ 2005)
Next: VirtualAllocEx returns a bad pointer in some processes
From: Elvandar on 19 Jan 2007 11:56 Hi all. I wrote an MFC application to make an HTTP file transfer between a client and a server. The application receives as input the list of servers to call (in this case, servers are remote devices with an embedded web server), and one by one it sends the file and closes the connection. The sequence of the operations made is this: 1) Dial-up call to device X 2) Open socket on port 80 3) HTTP POST of the file to the device 4) Wait for the response, and analysis to understand if the transfer has gone well or not 5) Open a new socket (after the response, the old socket is closed) 6) HTTP GET of the appropriate page to confirm operations to perform after the call is closed 7) Wait for the response and close socket 8) Hang up of the connection These operations are repeated for every device in the list. The problem is that with the first device all goes well, while from the second dial-up call, every time the method CSocket.Create() is called, the application hangs with a "Unhandled Exception: Access violation"... With a step-by-step analisys I saw the code is blocking here: * MAP_PP.cpp File void* CMapPtrToPtr::GetValueAt(void* key) const // find value (or return NULL -- NULL values not different as a result) { if (m_pHashTable == NULL) // CODE HANGS HERE!!! return NULL; UINT nHash = HashKey(key) % m_nHashTableSize; // see if it exists CAssoc* pAssoc; for (pAssoc = m_pHashTable[nHash]; pAssoc != NULL; pAssoc = pAssoc->pNext) { if (pAssoc->key == key) return pAssoc->value; } return NULL; } While the code executed in the operations listed above is this: * Thread to manage upload (here I removed every if and flow controls): while(Tmp != NULL) { DialUp(Tmp->PhoneNumber); CHTTPOnSocket* pClient = NULL; pClient = new CHTTPOnSocket(); pClient->InitializePostArguments(); pClient->AddPostArgument("FwFile",FwFilename,TRUE); pClient->DoRequest(SERVER_ADDRESS,UPLOAD_FW_PAGE,CHTTPOnSocket::RequestPostMultiPart); LPSTR Response = pClient->QueryHTTPResponse(); pClient->DoRequest(SERVER_ADDRESS, UPLOAD_OK_PAGE,CHTTPOnSocket::RequestGet); Response = pClient->QueryHTTPResponse(); HangUp(); pClient->~CHTTPOnSocket(); Tmp = Tmp->Next; } * Useful methods of the class CHTTPSocket to send/receive data on the socket Socket and SocketFile are defined as class attributes in CHTTPSocket.h in this way: CSocket* Socket; CSocketFile* SocketFile; CHTTPOnSocket::CHTTPOnSocket() { Socket = NULL; SocketFile = NULL; AfxSocketInit(NULL); } LPSTR CHTTPOnSocket::QueryHTTPResponse() { LPSTR RecBuffer = (LPSTR)::LocalAlloc(LPTR,RECEIVING_BUFFER); if(Socket == NULL) RecBuffer = NULL; else { try { CArchive *Receiver = new CArchive(SocketFile,CArchive::load); int n = Receiver->Read(RecBuffer,RECEIVING_BUFFER); Receiver->Close(); Receiver->~CArchive(); } catch (CException *e) { e->Delete(); RecBuffer = NULL; } this->CloseSocket(); } return RecBuffer; } void CHTTPOnSocket::CloseSocket() { try { SocketFile->Close(); SocketFile->~CSocketFile(); if(Socket != NULL) { Socket->Close(); Socket->~CSocket(); } } catch (CException *e) { e->Delete(); } Socket = NULL; } BOOL CHTTPOnSocket::DoRequest(LPCSTR ServerAddress, LPCSTR Url, int Method) { try { if(Socket == NULL) { Socket = new CSocket(); Socket->Create(); } Socket->Connect(ServerAddress,80); SocketFile = new CSocketFile(Socket); } catch(CException *e) { e->Delete(); return FALSE; } switch(Method) { case CHTTPOnSocket::RequestGet: return this->DoGet(ServerAddress, Url); break; case CHTTPOnSocket::RequestPost: return this->DoPost(ServerAddress, Url); break; case CHTTPOnSocket::RequestPostMultiPart: return this->DoPostMultiPart(ServerAddress, Url); break; default: return FALSE; break; } } BOOL CHTTPOnSocket::DoGet(LPCSTR ServerAddress, LPCSTR Url) { CString UrlToGet; try { CArchive *Sender = new CArchive(SocketFile,CArchive::store); UrlToGet.Format("GET /%s HTTP/1.1\r\n\r\n",Url); Sender->Write((PBYTE)UrlToGet.GetBuffer(UrlToGet.GetLength()),UrlToGet.GetLength()); Sender->Flush(); Sender->Close(); } catch (CException *e) { e->Delete(); return FALSE; } return TRUE; } BOOL CHTTPOnSocket::DoPostMultiPart(LPCSTR ServerAddress, LPCSTR Url) { BOOL bRet = FALSE; DWORD ContentLengthValue = GetContentLengthValue(); CString Headers = BuildPostHeaders(Url,ContentLengthValue); PBYTE MultipartData; MultipartData = (PBYTE)::LocalAlloc(LPTR, ContentLengthValue); GetMultipartData(MultipartData,ContentLengthValue); PBYTE PostRequest = (PBYTE)::LocalAlloc(LPTR,Headers.GetLength() + ContentLengthValue); PBYTE Tmp = PostRequest; ::CopyMemory(Tmp, Headers, Headers.GetLength()); Tmp += Headers.GetLength(); ::CopyMemory(Tmp, MultipartData, ContentLengthValue); // Here, in PostRequest we have the complete request to send to remote host try { CArchive *Sender = new CArchive(SocketFile,CArchive::store); Tmp = PostRequest; Sender->Write((PBYTE)Tmp,Headers.GetLength() + ContentLengthValue); Sender->Flush(); Sender->Close(); Sender->~CArchive(); bRet = TRUE; } catch (CException *e) { e->Delete(); } return bRet; } CHTTPOnSocket::~CHTTPOnSocket() { try { if(Socket != NULL) { Socket->Close(); Socket->~CSocket(); } } catch (CException* e) // Socket already closed { e->Delete(); } Socket = NULL; AfxSocketTerm(); } The problem is in the method DoRequest. When I call the second device, and executed the instruction pClient->DoRequest(SERVER_ADDRESS,UPLOAD_FW_PAGE,CHTTPOnSocket::RequestPostMultiPart); the application hangs on if(Socket == NULL) { Socket = new CSocket(); Socket->Create(); // CODE HANGS HERE!!! } of the method DoRequest in CHTTPSocket...I'm almost desperate, I suppose I tried everything with no luck...could anyone please give me a hand??? Thank you to anyone, and sorry for my bad English :P Elvandar
From: Elvandar on 19 Jan 2007 12:15 Elvandar has brought this to us : > Hi all. I wrote an MFC application to make an HTTP file transfer between a > client and a server. The application receives as input the list of servers to > call (in this case, servers are remote devices with an embedded web server), > and one by one it sends the file and closes the connection. The sequence of > the operations made is this: > > [CUT] Ok, doesn't matter. Just a fast search with google groups to find out it is a bug in vc++ 6 without sp3... :) I solved with a workaround! Sorry for the post, next time I'll first look on google, and after post to a newsgroup for help :P Elvandar
From: Scott McPhillips [MVP] on 19 Jan 2007 12:25 Elvandar wrote: > pClient = new CHTTPOnSocket(); > ... > ... > pClient->~CHTTPOnSocket(); Get rid of all your calls to destructors! That is the wrong way to destroy objects and it leaks memory too. delete pClient; -- Scott McPhillips [VC++ MVP]
From: Norbert Unterberg on 19 Jan 2007 18:04 Elvandar schrieb: > Elvandar has brought this to us : >> Hi all. I wrote an MFC application to make an HTTP file transfer >> between a client and a server. The application receives as input the >> list of servers to call (in this case, servers are remote devices with >> an embedded web server), and one by one it sends the file and closes >> the connection. The sequence of the operations made is this: >> >> [CUT] > > Ok, doesn't matter. Just a fast search with google groups to find out it > is a bug in vc++ 6 without sp3... :) I solved with a workaround! I hope the workaround was to install VC++ SP6! Norbert
From: Elvandar on 22 Jan 2007 03:53 Scott McPhillips [MVP] wrote : > Elvandar wrote: >> pClient = new CHTTPOnSocket(); >> ... >> ... >> pClient->~CHTTPOnSocket(); > > Get rid of all your calls to destructors! That is the wrong way to destroy > objects and it leaks memory too. > > delete pClient; Thank you Scott, I'm new to C++ so I thought the call to destructor was the right way to destroy objects! :)
|
Next
|
Last
Pages: 1 2 Prev: deploying mfc-based ActiveX control (VC++ 2005) Next: VirtualAllocEx returns a bad pointer in some processes |