InternetWriteFile



  • hallo allerseits!

    nach nun fast einer woche(!) suchen, lesen und fehlersuchen geb ichs fast auf, eine datei auf einen ftp-server zu laden.

    meine letzte hoffnung ist, dass mir hier eventuell jemand weiterhelfen kann.

    prinzipell wird folgende funktion aus meiner klasse als thread aufgerufen - funktioniert einwandfrei.
    weiters werden auch die daten auf den ftp-server hochgeladen - funktioniert soweit auch.

    ABER: dwNumberOfBytesWritten bleibt IMMER auf 0 stehen - lasse mir das jede sekunde mit meiner ausgabe-wrapper-funktion CFTPmt::_fptr_appLoggerFnc() im hintergrund über die konsole ausgeben.

    hier mal die funktion:

    unsigned int __stdcall CFTPmt::thread_UploadFile_Binaray( LPVOID lpvoidParam )
    {
    	// wait one second to give time to the system
    	Sleep(1000);
    
    	// cast lpvoid-data
    	UPLOADFILE_BIN * pUploadFileBin = (UPLOADFILE_BIN*)lpvoidParam;
    
    	// text output to application
    	CFTPmt::_fptr_appLoggerFnc( L"Preparing File for upload: " + pUploadFileBin->wsLocalFilename + L"\n" );
    
    	// read raw filedata into memory
    	FILE * pFile;
    	long lSize;
    	char * buffer_RAWData;
    	size_t result;
    
    	pFile = _wfopen ( pUploadFileBin->wsLocalFilename.c_str() , L"rb" );
    	if (pFile==NULL) 
    	{
    		// text output to application
    		CFTPmt::_fptr_appLoggerFnc( L"Error opening File: " + pUploadFileBin->wsLocalFilename + L"\n" );
    		pUploadFileBin->bError = TRUE;
    
    		// call the 'thread-finished' function
    		CFTPmt::onUploadFile_Binaray( pUploadFileBin );
    
    		// end calling thread - doesn't close the thread handle
    		unsigned int retVal = 0;
    		_endthreadex( retVal );
    		return retVal;
    	}
    
    	// obtain file size:
    	fseek (pFile , 0 , SEEK_END);
    	lSize = ftell (pFile);
    	rewind (pFile);
    
    	std::wostringstream wossa;
    	wossa << L"filesize in kb: " << ( lSize / 1024 ) << L"\n" << L"filesize in b: " << ( lSize ) << L"\n";
    	CFTPmt::_fptr_appLoggerFnc( wossa.str() );
    
    	if ( lSize <= 0 )
    	{
    		// text output to application
    		CFTPmt::_fptr_appLoggerFnc( L"Error getting File information: " + pUploadFileBin->wsLocalFilename + L"\n" );
    		pUploadFileBin->bError = TRUE;
    
    		// call the 'thread-finished' function
    		CFTPmt::onUploadFile_Binaray( pUploadFileBin );
    
    		// end calling thread - doesn't close the thread handle
    		unsigned int retVal = 0;
    		_endthreadex( retVal );
    		return retVal;
    	}
    
    	// allocate memory to contain the whole file:
    	buffer_RAWData = (char*) malloc (sizeof(char)*lSize);
    
    	if (buffer_RAWData == NULL) 
    	{
    		// text output to application
    		CFTPmt::_fptr_appLoggerFnc( L"Error: Out of memory!\n" );
    		pUploadFileBin->bError = TRUE;
    
    		// call the 'thread-finished' function
    		CFTPmt::onUploadFile_Binaray( pUploadFileBin );
    
    		// end calling thread - doesn't close the thread handle
    		unsigned int retVal = 0;
    		_endthreadex( retVal );
    		return retVal;
    	}
    
    	ZeroMemory( buffer_RAWData, sizeof(char)*lSize );
    
    	std::wostringstream wossb;
    	wossb <<  L"memory alloc size: " << sizeof(char)*lSize << L"\n";
    	CFTPmt::_fptr_appLoggerFnc( wossb.str() );
    
    	// copy the file into the buffer:
    	result = fread (buffer_RAWData,1, lSize ,pFile);
    	if (result != lSize)
    	{
    		// text output to application
    		CFTPmt::_fptr_appLoggerFnc( L"Error reading File: " + pUploadFileBin->wsLocalFilename + L"\n" );
    		pUploadFileBin->bError = TRUE;
    
    		// call the 'thread-finished' function
    		CFTPmt::onUploadFile_Binaray( pUploadFileBin );
    
    		// end calling thread - doesn't close the thread handle
    		unsigned int retVal = 0;
    		_endthreadex( retVal );
    		return retVal;
    	}
    
    	// text output to application
    	CFTPmt::_fptr_appLoggerFnc( L"Successfully read File: " + pUploadFileBin->wsLocalFilename + L"\n" );	
    
    	// the whole file is now loaded in the memory buffer.
    
    	// terminate
    	fclose (pFile);
    
    	// -------------------------------------- upload
    	// open remote-ftp-file for uploading
    	HINTERNET hOpenFile = FtpOpenFileW(
    		CFTPmt::_FTPConn.hConnect,
    		pUploadFileBin->wsRemoteFilename.c_str(),
    		GENERIC_WRITE,
    		FTP_TRANSFER_TYPE_BINARY,
    		NULL
    		);
    	if( hOpenFile == NULL )
    	{
    		// text output to application
    		CFTPmt::_fptr_appLoggerFnc( L"Error uploading File: " + pUploadFileBin->wsLocalFilename + L"\n" );
    		pUploadFileBin->bError = TRUE;
    
    		// free memory
    		free (buffer_RAWData);
    
    		// call the 'thread-finished' function
    		CFTPmt::onUploadFile_Binaray( pUploadFileBin );
    
    		// end calling thread - doesn't close the thread handle
    		unsigned int retVal = 0;
    		_endthreadex( retVal );
    		return retVal;
    	}
    
    	CFTPmt::_fptr_appLoggerFnc( L"FtpOpenFileW ok: \n" );
    
    	// progress upload
    	DWORD dwNumberOfBytesWritten = 0;
    	BOOL res;
    
    	std::wostringstream status;
    	while ( dwNumberOfBytesWritten < sizeof(char)*lSize )
    	{
    		res = InternetWriteFile(
    			hOpenFile,
    			buffer_RAWData,
    			sizeof(char)*lSize,
    			&dwNumberOfBytesWritten
    			);
    
    		status.str(L"");
    		status << ( dwNumberOfBytesWritten / 1024 ) << L" / " << ( sizeof(char)*lSize / 1024 ) << L" KB res=" << res << "\n";
    		CFTPmt::_fptr_appLoggerFnc( status.str() );
    		Sleep(1000);
    	}
    
    	if( !res )
    	{
    		// text output to application
    		std::wostringstream wosserrupl;
    		wosserrupl << L"Error uploading File: " << pUploadFileBin->wsLocalFilename << L"\n" << ( CFTPmt::getLastFTP_Response() ) << L"\n";
    		CFTPmt::_fptr_appLoggerFnc( wosserrupl.str() );
    
    		pUploadFileBin->bError = TRUE;
    
    		// call the 'thread-finished' function
    		CFTPmt::onUploadFile_Binaray( pUploadFileBin );
    
    		// end calling thread - doesn't close the thread handle
    		unsigned int retVal = 0;
    		_endthreadex( retVal );
    		return retVal;
    	}
    
    	std::wostringstream wossupl;
    	wossupl <<  L"Uploading File OK. \n" << ( CFTPmt::getLastFTP_Response() ) << L"\n";
    	CFTPmt::_fptr_appLoggerFnc( wossupl.str() );
    
    	// --------------------------------------- end upload 
    
    	// call the 'thread-finished' function
    	CFTPmt::onUploadFile_Binaray( pUploadFileBin );
    
    	// end calling thread - doesn't close the thread handle
    	unsigned int retVal = 0;
    	_endthreadex( retVal );
    	return retVal;
    
    }
    

    danke schon mal für eure hilfe
    lg


  • Mod

    Die Schleife ist doch unsinnig:

    while ( dwNumberOfBytesWritten < sizeof(char)*lSize ) 
        {
    

    Du schreibst doch alles auf einmal? Warum willst Du das öfters machen.
    Zudem veränderst Du nicht die Zeiger... Wenn Du in mehreren Blöcken schreiben würdest, nur dann würde eine Schleife hier Sinn machen.

    Zudem sehe ich keine Prüfung ob ein Fehler auftritt! Was ist den res? Was sagt GetLastError?

    Die Schleife bricht ja nicht mal bei einem Fehler ab. Bau doch erstmal eine richtige Fehlerbehandlung ein...



  • hi!

    ich hab mal den upload-teil wie folgt umgebaut

    // --------------------------------------------------------------------------------------- upload
    
    	// open remote-ftp-file for uploading
    
    	// text output to application
    	CFTPmt::_fptr_appLoggerFnc( L"open remote-ftp-file for uploading: " + pUploadFileBin->wsRemoteFilename + L"\n" );
    
    	HINTERNET hOpenFile = FtpOpenFileW(
    		CFTPmt::_FTPConn.hConnect,
    		pUploadFileBin->wsRemoteFilename.c_str(),
    		GENERIC_WRITE,
    		FTP_TRANSFER_TYPE_BINARY|INTERNET_FLAG_RESYNCHRONIZE,
    		NULL
    		);
    
    	// exit thread if FtpOpenFileW fails
    	if( hOpenFile == NULL )
    	{
    		// text output to application
    		CFTPmt::_fptr_appLoggerFnc( L"Error opening remote file for upload: " + pUploadFileBin->wsLocalFilename + L"\n" );
    		pUploadFileBin->bError = TRUE;
    
    		// free memory
    		free (buffer_RAWData);
    
    		// call the 'thread-finished' function
    		CFTPmt::onUploadFile_Binaray( pUploadFileBin );
    
    		// end calling thread - doesn't close the thread handle
    		unsigned int retVal = 0;
    		_endthreadex( retVal );
    		return retVal;
    	}
    
    	// FtpOpenFileW result was ok
    	CFTPmt::_fptr_appLoggerFnc( L"FtpOpenFileW ok: \n" );
    
    	// progress upload
    	DWORD dwNumberOfBytesWritten = 0;
    	BOOL res;
    	int	nChunkSize = 1024;
    	BOOL doProcess = TRUE;
    	std::wostringstream	status;
    	UINT tryAgainTimes = 3;
    	BOOL waiting = FALSE;
    
    	while ( doProcess ) // dwNumberOfBytesWritten < sizeof(char)*lSize
    	{
    		if( !waiting )
    		{
    			res = InternetWriteFile(
    				hOpenFile,
    				buffer_RAWData,
    				nChunkSize, // sizeof(char)*lSize
    				&dwNumberOfBytesWritten
    				);
    		}
    
    		if ( !res )
    		{
    			// text output to application
    			status.str(L"");
    			status << L"Error uploading File: " << pUploadFileBin->wsLocalFilename << L"\n LAST ERROR: " << GetLastError() << L" - " << ( CFTPmt::getLastFTP_Response() ) << L" res = " << res << L"\n";
    			CFTPmt::_fptr_appLoggerFnc( status.str() );
    
    			if( GetLastError() == 997 && tryAgainTimes > 0 ) // 997 = asynchronous I/O operation is pending !?
    			{
    				waiting = TRUE;
    				status.str(L"");
    				status << L"waiting for server - will try again " << tryAgainTimes << L" times ...\n";
    				CFTPmt::_fptr_appLoggerFnc( status.str() );
    				tryAgainTimes --;
    				Sleep(1000);
    			}
    			else
    			{
    				// set error flag for user of this class
    				pUploadFileBin->bError = TRUE;
    
    				// call the 'thread-finished' function
    				CFTPmt::onUploadFile_Binaray( pUploadFileBin );
    
    				// end calling thread - doesn't close the thread handle
    				unsigned int retVal = 0;
    				_endthreadex( retVal );
    				return retVal;
    			}			
    		}
    		else
    		{
    			status.str(L"");
    			status << ( dwNumberOfBytesWritten / 1024 ) << L" / " << ( sizeof(char)*lSize / 1024 ) << L" KB res=" << res << "\n";
    			CFTPmt::_fptr_appLoggerFnc( status.str() );
    			Sleep(1000);
    			buffer_RAWData += nChunkSize;
    			waiting = FALSE;
    		}
    
    	}
    
    	status.str(L"");
    	status <<  L"Uploading File OK. \n" << ( CFTPmt::getLastFTP_Response() ) << L"\n";
    	CFTPmt::_fptr_appLoggerFnc( status.str() );
    

    nun gibt es 2 symptome die auftreten:

    1.) am ftp-server existiert dieses file noch nicht dann lädt mein programm das file zwar im hintergrund hoch ( feststellbar im filezilla und F5 drücken ... )
    meldet aber folgende fehler:

    Connection to the FTP-Server established ...
    
    APP: onOpenFTPConnection called in MAIN b=0
    
    Preparing File for upload: D:\alexTestbilder.rar
    filesize in kb: 17270
    filesize in b: 17684836
    memory alloc size: 17684836
    Successfully read File: D:\alexTestbilder.rar
    
    open remote-ftp-file for uploading: /httpdocs/picture_library/alexTestbilder.rar
    
    FtpOpenFileW ok:
    
    Error uploading File: D:\alexTestbilder.rar
     LAST ERROR: 997 - ErrorId = 0 Error Message:  res = 0
    waiting for server - will try again 3 times ...
    
    Error uploading File: D:\alexTestbilder.rar
     LAST ERROR: 997 - ErrorId = 0 Error Message:  res = 0
    waiting for server - will try again 2 times ...
    
    Error uploading File: D:\alexTestbilder.rar
     LAST ERROR: 997 - ErrorId = 0 Error Message:  res = 0
    waiting for server - will try again 1 times ...
    
    Error uploading File: D:\alexTestbilder.rar
     LAST ERROR: 997 - ErrorId = 0 Error Message:  res = 0
    
    APP: onUploadFile_Binaray called in MAIN b=1
    
    Connection to the FTP-Server closed ...
    Connection to the Internet closed ...
    

    danach ist die datei am server ca. 1MB gross.

    wenn ich nun nochmal das programm starte, hängt es ca 1 minute beim aufruf von

    FtpOpenFileW
    

    und bricht dann mit meiner fehlermeldung

    Error opening remote file for upload: D:\alexTestbilder.rar
    

    ab. das file am server ist nun zwar da aber nur mehr 0kb gross.


Anmelden zum Antworten