Форум: "Начинающим";
Текущий архив: 2009.08.09;
Скачать: [xml.tar.bz2];
ВнизWinSock, передача файлов, клиент получает в два раза больше Найти похожие ветки
← →
winsockuser (2009-05-18 21:51) [0]Всем доброго времени суток.
Возникла проблема при написании клиента на 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-05-18 21:59) [1]Ты наверно код этот где-то стырил ?)
Где-то я уже видел эту шнягу)..
← →
winsockuser (2009-05-18 22:08) [2]Ошибаетесь. Код написан мною. Иначе зачем тырить код, который не работает? Впрочем, с ним и до этого были проблемы, кусок публиковался. Возможно, его ты и видел.
Есть ли комментарии по существу?
← →
Сергей М. © (2009-05-18 22:27) [3]Есть.
> recv(sServerListen,
Почему не 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:30) [4]
> sServerListen,
Исторически сложилось.
>bigrecy
array[0..4196] of char
← →
Сергей М. © (2009-05-18 22:35) [5]
> Исторически сложилось
Врать не есть гут.
А где ответы на прочие уточняющие контрвопросы ?
← →
FireMan_Alexey © (2009-05-18 23:22) [6]Попробуй придумать такой код :)
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;
← →
FireMan_Alexey © (2009-05-18 23:26) [7]Да не забудь закрыть Socket после цикла!!!
← →
Сергей М. © (2009-05-18 23:31) [8]
> FireMan_Alexey © (18.05.09 23:22) [6]
Без подробностей конкретного прикладного протокола твой пример - медвежья услуга)
← →
winsockuser (2009-05-18 23:47) [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 ‘| `э @ TсЗ ”ьЗ йђ|‘|яяяя‘|P·Ђ| @ $·Ђ| `э9·Ђ| М РцЗ РцЗ U‹‘|з‹‘|? ‘ р I‘ x‘ Qљ”|4чЗ @‘ з‹‘|< « ˜ x‘ x‘ ЁI‘ @ (« ˜ и« ˜I‘ М р x‘ x‘ ? I‘ Y « I‘ I‘ I‘ h‘ x‘ ‘ ґфЗ DчЗ йђ|р‹‘|яяяяз‹‘|TчЗ PС–|‘ 4С–| ‘ ‘
Я пробовал преобразовать в Pansichar, но безуспешно. Думаю, причина как-то связана с глобальной перетипизацией в новой дельфе, ибо в седьмой этот код работал без проблем.
Сергей М:
Даже не вникая в "подробности конкретного прикладного протокола" могу сказать, что передача файла идет без какого-либо сжатия\шифрование, после еофа сокет закрывается сервером. И "медвежья услуга" оказалась куда более полезной чем бессмысленные риторические вопросы,не находишь? И с чего ты вообще взял, что я вру?
Ах да, чуть не забыл, что какое слово означает М. в твоем нике?
← →
Slym © (2009-05-19 04:47) [10]два раза
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;
← →
Slym © (2009-05-19 05:13) [11]
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.
← →
Сергей М. © (2009-05-19 08:43) [12]
> бессмысленные риторические вопросы,не находишь?
Не нахожу.
Огрызок кода, лишенный логики и авторских комментариев, куда более бессмысленен)
Продолжай париться.
← →
Anatoly Podgoretsky © (2009-05-19 09:27) [13]Невнятно объясняешься, а для таких у нас есть особая конференция.
Но намек дам - SizeOf(Char)
← →
FireMan_Alexey © (2009-05-19 14:15) [14]
>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) .
← →
CrytoGen (2009-05-19 14:32) [15]В 2009-м конечно Char 2 байта.
← →
Eraser © (2009-05-19 15:12) [16]передавать данные в строках - не очень удачная мысль.
← →
болванчег (2009-06-11 22:01) [17]замени file of char на file of AnsiChar
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2009.08.09;
Скачать: [xml.tar.bz2];
Память: 0.52 MB
Время: 0.005 c