Добрый день. У меня есть код ,который посылает запрос сервера на скачку файла. Фрагмент кода, который принимает данные выглядит так: Код (Text): invoke ioctlsocket,hSocket1,FIONREAD,addr sizetoread .IF eax==NULL invoke GlobalAlloc,GHND,sizetoread ; Выделяем память для буфера считываемых данных mov mHandle,eax invoke GlobalLock,eax mov buffer,eax invoke recv,hSocket1,buffer,sizetoread,0 ; считываем данные с сокета mov actual_data_read, eax .IF actual_data_read == 0 ;если нихуя не прочиталось invoke MessageBox, NULL, addr wsaError, addr Hello, MB_OK + MB_ICONSTOP invoke closesocket, hSocket1 invoke WSACleanup mov WithoutHeaderSize,0 ;invoke TerminateThread,hThread,0 .ENDIF invoke CreateFile,addr TESTfile,GENERIC_WRITE,FILE_SHARE_READ,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_ARCHIVE,NULL mov hFile, eax invoke WriteFile,hFile,buffer,actual_data_read,addr bWritten,NULL invoke CloseHandle, hFile Суть проблемы в том, что из сокета считывается (включая HTTP заголовок) 8 192 байта. И, соответственно, пишется в файл. Как скачать файл полностью? Я что-то слышал про пофрагментное скачивание , но по сути ничего не знаю. Есть какие-нить идеи или статьи на эту тему? Спасибо!
Код (Text): GetInetFile proc LOCAL hSession :DWORD LOCAL hUrl :DWORD LOCAL hSave :HANDLE LOCAL lpBuffer [BUFSIZ] :BYTE LOCAL dwBytesRead :DWORD LOCAL dwPos :DWORD LOCAL dwBytesWritten :DWORD invoke GetModuleFileName, hInstance, addr AppName, sizeof AppName mov hSession, FUNC(InternetOpen, addr AppName, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, NULL) .if hSession == INVALID_HANDLE_VALUE mov eax, INVALID_HANDLE_VALUE ret .endif mov hUrl, FUNC(InternetOpenUrl, hSession, addr szUrl, NULL, NULL, NULL, NULL) .if (hUrl == INVALID_HANDLE_VALUE || hUrl == 0) mov eax, INVALID_HANDLE_VALUE ret .endif invoke DeleteFile, addr szSave ;удаляем файл ибо без етово файл постояно нарастает mov hSave, FUNC(CreateFile, addr szSave, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL) .if hSave == INVALID_HANDLE_VALUE mov eax, INVALID_HANDLE_VALUE ret .endif elsecopy: invoke InternetReadFile, hUrl, addr lpBuffer, BUFSIZ, addr dwBytesRead .if eax == TRUE mov dwPos, FUNC(SetFilePointer, hSave, NULL, NULL, FILE_END) mov eax, dwPos add eax, dwBytesRead invoke LockFile, hSave, dwPos, NULL, eax, NULL invoke WriteFile, hSave, addr lpBuffer, dwBytesRead, addr dwBytesWritten, NULL mov eax, dwPos add eax, dwBytesRead invoke UnlockFile, hSave, dwPos, NULL, eax, NULL .endif .if dwBytesRead == BUFSIZ jmp elsecopy .endif invoke InternetCloseHandle, hSession invoke InternetCloseHandle, hUrl invoke CloseHandle, hSave mov eax, ERROR_SUCCESS ret GetInetFile endp
_mikityak_, спасибо большое! Сегодня обязательно это попробую, но один вопрос остаётся открытым. Как это всётаки делается с помощью функций прямой работы с сокетом типа recv? И где можно глянуть исходник функции InternetReadFile ? Спасибо!
Спасибо! Камментрии такого уровня мне по нраву Код (Text): start: ;с этого слова начинается код программы Суть моего вопроса в том была, что при одном заходе с recv, ты скачать не можешь полностью файл, и по этому с этой функцией нужно делать цикл. И тут нюанс в том, как считывать из сокета данные не сначала каждый раз, а со смещением равным сумме данных считанных в предыдущих контурах цикла. Сказал как мог =)\ вот и всё в принципе) ЗЫ Ещё то что некоторые антивирусы неадекватно реагируют на этот код - не есть гуд =(