Click to See Complete Forum and Search --> : WinInet Blocking Calls


Flagrant99
July 18th, 1999, 11:19 PM
I am using CInternetSession, CFtpConnection and CInternetFile to download files. When the user cancels, I call CInternetFile::Close()from a seperate thread. This does not stop the blocking call to CInternetFile::Read(). It hangs until the server sends a response back. If my code has hasn't gotten to the Read() yet CInternetSession::Close() and CFtpConnection::Close() work. They kill the blocking call in the worker thread, but I can't get the HINTERNETHANDLE to close once in the Read(). I even tried doing things without MFC and using the API functions FtpOpenFile()and InternetReadFile(). Calling InternetCloseHandle() didn't work. It still hangs on slow servers. The documentation for FtpOpenFile() states "If InternetCloseHandle closes the handle before all the data has been transferred, the transfer is terminated." Does anybody have an example of getting this to work. Getting The Read() to terminate immediately on user cancellation without having to wait for all of the retries and timeouts? Preferably using MFC. Any ideas?
Thanks.

Flagrant99
July 21st, 1999, 08:52 AM
Let me rephrase my question:
Has anybody tried calling CInternetFile::Close()from a seperate thread
while CInternetFile::Read() is reading data. Isn't CInternetFile::Close()
supposed to stop the Read()?
Also, does anybody have any info on InternetReadFileEx(). I can't get it to work.

HINTERNET h_open =InternetOpen("Blah", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
HINTERNET h_connect =InternetConnect(h_open, mt_ptr->Server, INTERNET_DEFAULT_FTP_PORT, NULL, NULL, INTERNET_SERVICE_FTP, 0, 0);
CString temp_str;
ftpfile = FtpOpenFile(h_connect, full_ftp_name, GENERIC_READ, FTP_TRANSFER_TYPE_BINARY, 0);
if (ftpfile == NULL) {
temp_str.Format("Unable to FtpOpenFile %d", ::GetLastError());
AfxMessageBox(temp_str); }

char buffer[DL_BUFFER_SIZE];
unsigned long amount_read = DL_BUFFER_SIZE;
unsigned int total_read = 0;

INTERNET_BUFFERS ib;
ib.dwStructSize = sizeof(INTERNET_BUFFERS);
ib.Next = NULL;
ib.lpcszHeader = NULL;
ib.dwHeadersLength = 0;
ib.dwHeadersTotal = 0;
ib.lpvBuffer = buffer;
ib.dwBufferLength = DL_BUFFER_SIZE;
ib.dwBufferTotal = 0;
ib.dwOffsetLow = 0;
ib.dwOffsetHigh = 0;

while (amount_read == DL_BUFFER_SIZE && mt_ptr->abort_flag == FALSE)
{
BOOL result = ::InternetReadFileEx(ftpfile, &ib, 0, 0);
if (!result) {
temp_str.Format("InternetReadFileEx() Error %d", ::GetLastError());
AfxMessageBox(temp_str);
break;
}
cfo.Write(buffer, amount_read);//Write this to our data file
total_read += amount_read;
}

InternetReadFileEx() always returns an error stating that I am passing it the wrong handle. ANybody know what I am doing wrong?

Imran Rajwani
July 21st, 1999, 10:57 AM
You should try using the async mode. In InternetOpen(), the last parameter is the flag. specify INTERNET_FLAG_ASYNC for the flag value.
Async calls will not cause the blocks you are experiencing. But the will work differently. See the online documentation to figure out how it will fit your model.

Another approach which would be much easier, is that if you can find the actual SOCKET handle associated with the FTP connection. closesockt() call on that handle will not block, and ftpread etc() will immediately be aborted with i/o erros.

Sonu
January 31st, 2000, 05:20 AM
hi,
sorry this mail is not a answer to u'r mail but was wondering if u could help me out.i want my application to download files and save that file on my hard disk.i have started off using WinInet ,but am encountering some problems.u have mentioned that u are already able to do that.could u give me a brief idea how to go about it.sorry for the trouble,but it'll be a big help if u can guide me here.
thanks.
sonu

srclore
July 31st, 2003, 12:52 PM
Hi all,

I am also having problems with the blocking nature of the Read() call in the CInternetFile class. I read the above posts for possible solutions to my problems and saw that setting the INTERNET_FLAG_ASYNC flag to be a promising solution.

Unfortunately, there is an assertation being thrown in INet.cpp at line 419... I looked in the file and found the following ASSERT in the constructor for CInternetSession...

ASSERT((dwFlags & INTERNET_FLAG_ASYNC) == 0);

Um........ wha?......

Then I looked in the documentation at the possible values for the dwOption parameter to InternetQueryOption and found this line:

INTERNET_OPTION_ASYNC - Not Currently Implemented.

What's going on here?! Is the async mode not implemented?

Basically, every time I try to instantiate my CInternetSession object, my app crashes because it either throws an ASSERT in debug mode or thows a "debug assert thrown" message in release mode.

Any thoughts?

srclore
July 31st, 2003, 04:25 PM
Nevermind, just did a little more digging and discovered that async internet communications IS NOT SUPPORTED AT ALL IN MFC!

...gah.... gotta love 'em