Передача файлов на сервер ( HTTP)

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by winsock, 10 Oct 2010.

  1. winsock

    winsock New Member

    Joined:
    15 Aug 2010
    Messages:
    57
    Likes Received:
    2
    Reputations:
    0
    Возможно ли передавать файл кусками ?

    Т.е. многократно вызывать send для передачи файла на сервер.


    Если так , то сервер записывает только первый кусок.
    Code:
    HANDLE hFile= CreateFile(fileName,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
    	if(!hFile)
    		return 0;
    
    	if(!Connect(host))
    		return NULL;
    	
    	
    	int size = GetFileSize(hFile,0);
    	char uploadBuff[MAX_PATH];
    	wsprintfA(uploadBuff,"POST %s HTTP/1.1\r\n"
    					     "Host: %s\r\n"
    					     "User-Agent: Mozilla/4.8 [en](Windows NT 5.0; U)\r\n"
    						 "Content-Type: application/x-www-form-urlencoded\r\n"
    						 "Content-length: %d\r\n\r\n"
    					     "uploadFile=",query,host,size+11);
    
    
    	if(send(httpsock,uploadBuff,lstrlenA(uploadBuff),0)==SOCKET_ERROR){
    		closesocket(httpsock);
    		CloseHandle(hFile);
    		return 0;
    	}
    
    
    	
    
    
    	HANDLE hEndRead=CreateEvent(NULL,FALSE,FALSE,NULL);
    
    	DWORD read;
    	
    	OVERLAPPED ovl;
    	ovl.Offset=0;
    	ovl.OffsetHigh=0;
    	ovl.hEvent=hEndRead;
    	
    	do
    	{
    		if(!ReadFile(hFile,&uploadBuff,MAX_PATH,&read,&ovl) && GetLastError()!=ERROR_IO_PENDING)
    			break;
    		
    		WaitForSingleObject(hEndRead, 5000);
    		
    		if(send(httpsock,uploadBuff,lstrlenA(uploadBuff),0)==SOCKET_ERROR)
    			break;
    
    		ovl.Offset += lstrlenA(uploadBuff);
    		
    	}while(ovl.Offset<size);
    		
    	closesocket(httpsock);
    	CloseHandle(hFile);
    	CloseHandle(hEndRead);
    

    Или может нужно хитный php скрипт писать ?
     
  2. Kandi

    Kandi Member

    Joined:
    18 Nov 2009
    Messages:
    344
    Likes Received:
    17
    Reputations:
    0
    Скорее нет, чем да!
    Взять в пример ту же копию файлов на Windows, если ты один и тот же файл вставишь в папку, то он не будет в неё в два раза быстрее копироваться, а создастся копия. Так же и здесь.

    З.Ы. Лично мне так кажется, точно не могу сказать!
     
  3. GRRRL Power

    GRRRL Power Elder - Старейшина

    Joined:
    13 Jul 2010
    Messages:
    823
    Likes Received:
    185
    Reputations:
    84
    Вообще, по-хорошему, так и надо делать. У функции send есть внутренний буфер, больше которого она передать будет не в состоянии за один раз, поэтому придется передавать большие файлы по кускам, вызывая send несколько раз. Почему не принимает сервер - это уже какие-то ошибки в программировании.
     
  4. winsock

    winsock New Member

    Joined:
    15 Aug 2010
    Messages:
    57
    Likes Received:
    2
    Reputations:
    0
    Теперь другая проблема

    все спец символы пишутся как \(спец символ) ,как исправить ?

    т.е. вместо CString sProcessName ( "FS" );

    CString sProcessName ( \"FS\" );
     
    #4 winsock, 15 Oct 2010
    Last edited: 15 Oct 2010
  5. Gar|k

    Gar|k Moderator

    Joined:
    20 Mar 2009
    Messages:
    1,166
    Likes Received:
    266
    Reputations:
    82
    чет бредовый код... lstrlenA(uploadBuff) - ты что текстовый файл закачиваешь?
    к тому же в &read - тебе вернется количество прочитанных байт. Спрашивается зачем lstrlenA(uploadBuff)?

    MAX_PATH = 256 байт выдели хотя бы 1024
    к тому же send возвращает количество переданных байт поэтому строчка ovl.Offset += lstrlenA(uploadBuff); это бред... может send за один присест передала 10 байт, а ты читаешь файл дальше.

    ВЫВОД: RTFM
     
    _________________________
  6. winsock

    winsock New Member

    Joined:
    15 Aug 2010
    Messages:
    57
    Likes Received:
    2
    Reputations:
    0
    не суть . Переделал это уже.Файл передается корректно,за исключением того , что написал выше.
    Из за чего такое может быть ?


    php скрипт

    Code:
    function SaveFile($uploadFile, $fileName)
    {
        $filehandle = fopen('reports/'.$fileName, "w");
        fputs($filehandle, $uploadFile);
        fclose($filehandle);
    }
    
    
    Кстати да,

    Если поток открыт в текстовом режиме, могут произойти преобразования некоторых символов. Это значит, что однозначного отображения строки в файл может и не быть. Однако если поток открыт в двоичном режиме, никаких преобразований символов не будет и строка отобразится в файл "один к одному".

    но ведь юникс не поддерживает wb(хостинги на нем обычно)

    Теперь примерно представляю из за чего, попробую сам исправить код.
     
    #6 winsock, 15 Oct 2010
    Last edited: 15 Oct 2010
  7. Gar|k

    Gar|k Moderator

    Joined:
    20 Mar 2009
    Messages:
    1,166
    Likes Received:
    266
    Reputations:
    82
    2 winsock: "CString sProcessName ( \"FS\" );" ай-ай-ай, как можно не знать что начиная с ~ 4 версии PHP деректива 'magic_quotes_gpc' включена по умолчанию. Поэтому нужно пользоваться функцией stripslashes если нужно, перед этим проверив magic_quotes_gpc вызвав ini_get
     
    _________________________
  8. roxblnfk

    roxblnfk Elder - Старейшина

    Joined:
    6 Feb 2010
    Messages:
    189
    Likes Received:
    42
    Reputations:
    19
    в принципе скрипт на передачу файлов по кускам через POST я уже писал как то... только в соседней теме — на PHP
    /showthread.php?p=2156929#post2156929