Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

WinSock, передача файлов, клиент получает в два раза больше [WinXP]


winsockuser ©   (2009-05-18 21:51:00) 

Всем доброго времени суток.
Возникла проблема при написании клиента на delphi 2009 для получения файлов. Цель - получить от сервера файл(не текст, как правило приложение\мп3). Сам сервер написан на перле и гарантированно работает, проверено никсовым клиентом на том же перле. Обязательна реализация на WinSock, никакие иные сетевые компоненты неприемлемы. Пытаюсь использовать следующий код:

[DELPHI]      

      ....

      // outy - хендл файла, в который надо произвести запись,
      // открытый через AssignFile и ReWrite. тип - file of char

     while (iret<>0) do
     begin
       iret := recv(sServerListen, bigrecy, length(bigrecy), 0);

     iRet := 1;
     while (iRet<>0) do
     begin
       iRet := Recv(sServerListen, BigRecy, length(BigRecy), 0);
       if (iRet = 0) then
        break;
       BlockWrite(outy, bigrecy, iret, counter);
     end;

     close (Outy);
     Stringy := '';
   end;

   ...
[/DELPHI]

Проблема заключается в том, что этот код пишет примерно в два раза больше данных, чем передается на самом деле. Причем при проверке на текстовых файлах выяснилось, что пишется непонятно что в совершенно невнятной кодировке. Подскажите пожалуйста, в чем может быть проблема, и как, соответственно, ее исправить?


болванчег   (2009-06-11 22:01:00) [1]

замени file of char на file of AnsiChar


Eraser   (2009-05-19 15:12:00) [2]

передавать данные в строках - не очень удачная мысль.


CrytoGen   (2009-05-19 14:32:00) [3]

В 2009-м конечно Char 2 байта.


FireMan_Alexey   (2009-05-19 14:15:00) [4]


>Anatoly Podgoretsky ©

А я сразу не заметил :)


> winsockuser


Короче ты не правильно описал переменную файла :)

Или меняй на
Var
...
TvoyFile:File;
...
AssignFile(TvoyFile,<...>);
Rewrite(TvoyFile, 1); //размер минимальной записи в файле

Или используй такую конструкцию
Var
  TvoyFile;Integer;
...
 TvoyFile:=FileCreate(FileName);
  If TvoyFile=-1 Then {ошибка создания файла} Exit;
 
...
 WriteSize:=FileWrite(TvoyFile,Buffer,RecvSize);
 If WriteSize<>RecvSize Then
   {ошибка записи в файл} Exit;
...

 FileClose(TvoyFile);

А еще я думаю, что у тебя возможно под сам Char может отводиться 2 байта(как у Юникод-а). И таким образом у тебя одна запись файла равна 2 байтам. Вот у тебя и растет размер файла. попробуй использовать Byte :) (он и в Африке Byte) .


Anatoly Podgoretsky   (2009-05-19 09:27:00) [5]

Невнятно объясняешься, а для таких у нас есть особая конференция.
Но намек дам - SizeOf(Char)


Сергей М.   (2009-05-19 08:43:00) [6]


> бессмысленные риторические вопросы,не находишь?


Не нахожу.

Огрызок кода, лишенный логики и авторских комментариев, куда более бессмысленен)

Продолжай париться.


Slym   (2009-05-19 05:13:00) [7]

program Project1;

{$APPTYPE CONSOLE}

uses
 Windows, WinSock, SysUtils;

function HostToAddr(const AHost:string):Longint;
Var Host:PHostEnt;
begin
 Result:=inet_addr(PChar(AHost));
 if Result=INADDR_NONE then
 begin
   Host:=GetHostByName(PChar(AHost));
   if Host<>nil then
     Result:=PInAddr(Host^.h_addr^)^.S_addr;
 end;
end;

const
 RemoteHost='localhost';
 RemotePort=19;
var
 WSAData:TWSAData;
 SockAddr:TSockAddr;
 Sock:TSocket;
 Buf:array[0..4095] of byte;
 readed:integer;
 OutFile:file of byte;
begin
 if WSAStartup($101,WSAData)<>0 then raise Exception.Create('WSAStartup');
 Sock:=socket(AF_INET,SOCK_STREAM,0);
 if Sock=-1 then  raise Exception.Create('socket');
 FillChar(SockAddr,SizeOf(SockAddr),0);
 SockAddr.sin_family:=AF_INET;
 SockAddr.sin_port:=swap(RemotePort);
 SockAddr.sin_addr.S_addr:=HostToaddr(RemoteHost);
 if Connect(Sock,SockAddr,SizeOf(SockAddr))<>0 then
 begin
   CloseSocket(Sock);
   raise Exception.Create('Connect');
 end;
 AssignFile(OutFile,'c:\log.txt');
 Rewrite(OutFile);
 while true do
 begin
   readed:=recv(Sock, Buf, SizeOf(Buf), 0);
   if readed<=0 then break;
   BlockWrite(OutFile, Buf, readed);
 end;
 CloseFile(OutFile);
 CloseSocket(Sock);
 WSACleanup;
end.


Slym   (2009-05-19 04:47:00) [8]

два раза
while (iret<>0) do
    begin
      iret := recv(sServerListen, bigrecy, length(bigrecy), 0);

    iRet := 1;
    while (iRet<>0) do
    begin
      iRet := Recv(sServerListen, BigRecy, length(BigRecy), 0);
      if (iRet = 0) then
       break;
      BlockWrite(outy, bigrecy, iret, counter);
    end;


winsockuser   (2009-05-18 23:47:00) [9]

FireMan_Alexey: Все, в общем-то так, но проблема осталась, в файл помимо нормального текста пишется, подозреваю, оный текст в какой-то непонятной кодировке. Пример:

The first ten, collectively known as the Bill of Rights, were ratified simultaneously. The following seventeen were ratified separately.

The Bill of Rights (1?10)
Main article: United States Bill of Rights
United States Bill of Rights currently housed in the National Archives.
Wikisource
Wikisource has original text related to this article:
United States Bill of Rights

It is commonly understood that the Bill of Rights was not originally intend                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          \x2                                                                                                                                                                                                                                                                                                                                                                                                                               \x3\x3‘|         `э\x7F \x1@ TсЗ     ”ьЗ  йђ|\x8\x3‘|яяяя\x3\x3‘|P·Ђ|  @ $·Ђ| `э\x7F9·Ђ|                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            М   РцЗ РцЗ U‹‘|з‹‘|€     ‘ \x1                       р\x6       I‘     \x18       x\x1‘                       \x14 Qљ”|4чЗ @\x6‘ з‹‘|<     \x14 \x1                       \x10\x1       «\x14     \x1C       ˜\x2\x14                         x\x1‘         \x4               x\x1‘ ЁI‘                                                     @\x2\x14 \x10   («\x14 ˜\x2\x14         \x3       и«\x14                             ˜I‘                         М           р\x6              x\x1‘ x\x1‘ €   \x8I‘             \x14       Y       \x18«\x14      I‘      I‘ \x8I‘     \x14           \x10\x1                  h\x1‘   \x3 x\x1‘       ‘ ґфЗ \xB   DчЗ  йђ|р‹‘|яяяяз‹‘|TчЗ PС–|\x8\x6‘ 4С–|  ‘       ‘ \x10  


Я пробовал преобразовать в Pansichar, но безуспешно. Думаю, причина как-то связана с глобальной перетипизацией в новой дельфе, ибо в седьмой этот код работал без проблем.

Сергей М:
Даже не вникая в "подробности конкретного прикладного протокола" могу сказать, что передача файла идет без какого-либо сжатия\шифрование, после еофа сокет закрывается сервером. И "медвежья услуга" оказалась куда  более полезной чем бессмысленные риторические вопросы,не находишь? И с чего ты вообще взял, что я вру?
Ах да, чуть не забыл, что какое слово означает М. в твоем нике?


Сергей М.   (2009-05-18 23:31:00) [10]


> FireMan_Alexey ©   (18.05.09 23:22) [6]


Без подробностей конкретного прикладного протокола твой пример - медвежья услуга)


FireMan_Alexey   (2009-05-18 23:26:00) [11]

Да не забудь закрыть Socket после цикла!!!


FireMan_Alexey   (2009-05-18 23:22:00) [12]

Попробуй придумать такой код :)

While True do
Begin
 RecvSize:=Recv(Sock,Buff,SizeOf(Buff),0);
 If RecvSize=0 Then
   Begin
      Close(TvoyFile);
      Break;
   End
 Else
   If RecvSize<0 then
     Begin
        DoError;
        Close(TvoyFile);
        Break;
     End
   Else
       Begin
          BlockWrite(TvoyFile,Buff,RecvSize);
       End;
End;


Сергей М.   (2009-05-18 22:35:00) [13]


> Исторически сложилось


Врать не есть гут.

А где ответы на прочие уточняющие контрвопросы ?


winsockuser   (2009-05-18 22:30:00) [14]


> sServerListen,


Исторически сложилось.

>bigrecy


array[0..4196] of char


Сергей М.   (2009-05-18 22:27:00) [15]

Есть.


> recv(sServer Listen,


Почему не AcceptedClientSocket?


> bigrecy


Чтобы узнать тип этой переменной, нужно просить  у тебя высочайшего соизволения, так ?


>      while (iret<>0) do
>      begin
>        iret := recv(sServerListen, bigrecy, length(bigrecy),
>  0);


Что за бредовый цикл ?


>  iRet := 1;


Что за непонятное присвоение единицы ?


>      while (iRet<>0) do
>      begin
>        iRet := Recv(sServerListen, BigRecy, length(BigRecy),
>  0);
>        if (iRet = 0) then
>         break;
>        BlockWrite(outy, bigrecy, iret, counter);
>      end;
>


Что за еще более бредовый цикл ?

Давай уже комментируй каждуюстрочку своего кода, если он написан тобой- что делается, зачем делается и т.д. и т.п. ..


winsockuser   (2009-05-18 22:08:00) [16]

Ошибаетесь. Код написан мною. Иначе зачем тырить код, который не работает? Впрочем, с ним и до этого были проблемы, кусок публиковался. Возможно, его ты и видел.

Есть ли комментарии по существу?


Сергей М.   (2009-05-18 21:59:00) [17]

Ты наверно код этот где-то стырил ?)

Где-то я уже видел эту шнягу)..


Наверх

Титульная страница Поиск, карта сайта Написать письмо