[Delphi][Sockets] проблемы с получением изображения

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by vvs777, 4 Aug 2008.

  1. vvs777

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

    Joined:
    16 Nov 2004
    Messages:
    394
    Likes Received:
    213
    Reputations:
    4
    Прошу помочь разобраться а то я че-то торможу не могу понять откуда берется г**но.

    Delphi. Uses WinSock.
    TCP. Connect на 80 порт, GET, save to file.

    Code:
    function wsrecvstring(mailsocket:TSocket; var L:Longint):string;
    var
       buffer:array[1..64000] of byte;
       i:integer;
       buffstr:string;
    begin
         buffstr:='';
         fillchar(buffer,sizeof(buffer),0);
         l:=winsock.recv(mailsocket,buffer[1],sizeof(buffer),0);
         if L>0 then
         for i:=1 to L do
         begin
              buffstr:=buffstr+chr(buffer[i]);
         end;
         try
            result:=buffstr;
         except
            result:='';
         end;
    end;
    
    ...
    heads:='';
    heads:=wsrecvstring(mysock,L);
    np:=1;
    repeat
              s:=wsrecvstring(mysock,L);
              heads:=heads+s;
    until l<1;
    При этом в полученном содержимом (для хтмл-страниц оно неипет, а вот бинарники засирает)
    иногда появляются конструкции вида
    это типа слитно.
    Например
    - ср**ая тысяча
    потом в том эе файле еще раз она же, потом f56, 5321, и в разных файлах свое. В конце 0 и неско CRLF подрял.
    Откуда берется не ясно.
    Данные (картинки и тестовые до 25кб - остальные не пробовал) с сервера приходят одним цельным пакетом (когда-то сталкивался с тем что на некоторых серваках заголовок идет одним пакетом, данные остальными, потом увидел что это не обязательно
    и если это криво склеивать вместе...
    хотя у меня не криво
    heads:=heads+s; без мусора.
    ).

    Может кто видел это раньше?
    PS: предложения типа юзай wininet/indy/nm/fp не принимаются. Надо на сокетах и только.
     
    #1 vvs777, 4 Aug 2008
    Last edited by a moderator: 4 Aug 2008
    1 person likes this.
  2. alamat

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

    Joined:
    6 Aug 2007
    Messages:
    18
    Likes Received:
    3
    Reputations:
    0
    У меня тоже была такая хня и до сих пор есть на некоторых HTTP серверах... непонятно откуда она берется.. но я бы посоветовал почитать rfc
     
  3. slesh

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

    Joined:
    5 Mar 2007
    Messages:
    2,702
    Likes Received:
    1,224
    Reputations:
    455
    лучше читай чуть по другому.
    Code:
    var
       buffer:array[0..64000] of byte;
       i:integer;
       buffstr:string;
    begin
       buffstr:='';
       repeat
        l:=winsock.recv(mailsocket,buffer,sizeof(buffer),0);
        buffstr:=buffstr+copy(buffer,1,l);
       until l<=0;
      result:=buffstr;
    
    может быть чуть не правильно. нет компилятора под рукой проверить.
    но примерно так ты скачаешь полностью всё что прислал сервер.
    А на счет тысячи - хз сам встречался что добавляют.
     
  4. vvs777

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

    Joined:
    16 Nov 2004
    Messages:
    394
    Likes Received:
    213
    Reputations:
    4
    В принципе да, copy(buffer,1,l);.
    Но я же говорю, все приходит одним пакетом!!!
    Лажа находится в середине пакета, прочитанного за 1 вызов recv().
    Вот в чем проблема.
    Неужели приййдется юзать WSARecv? я ж это ненавижу...
    Вот заюзал wsaRecvEx(), теперь каждый файл состоит из 2 кусков, опять тысяча в начале и все, 2-3 лажи во втрором куске и ноль в конце...
    Как с этим браузеры борятся, не могу понять.
    И никогда раньше не слышал о том что сервер может вставлять куски хлама в данные. Только заголовки!
     
    #4 vvs777, 4 Aug 2008
    Last edited: 4 Aug 2008
  5. life96

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

    Joined:
    9 Apr 2008
    Messages:
    51
    Likes Received:
    18
    Reputations:
    23
    это протокол Http/1.1 Imho
    попробуй как то заставить работать в Http/1.0, там этого нет
    (как - не знаю, но это определятся запросом Get)
     
  6. slesh

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

    Joined:
    5 Mar 2007
    Messages:
    2,702
    Likes Received:
    1,224
    Reputations:
    455
    дык это и есть в запросе
    GET /image.jpg HTTP/1.0 или GET /image.jpg HTTP/1.1
     
  7. life96

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

    Joined:
    9 Apr 2008
    Messages:
    51
    Likes Received:
    18
    Reputations:
    23
    ну правильно, но я же не знаю как он там (или кто за него) запросы формирует :)
    вчера кстати попробовал загружать картинки с нескольких серверов, никто в режиме HTTP/1.1 чанки не использовал %( vvs777 дай пример сервера с которым у тебя "проблемы"
     
  8. vvs777

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

    Joined:
    16 Nov 2004
    Messages:
    394
    Likes Received:
    213
    Reputations:
    4
    Нашел в чем дело, топик можно закрывать.
    в логи если глянуть - Chunked. Вот его надо было обрабатывать.