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

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

Не возвращается количество полученных байт в блокирующисокетах??? [D6, Win2k]


Страницы:   1 2 3

slgeo ©   (2004-03-19 10:04:00) 

У меня идет обмен по блокирующим сокетам, а точнее передача файла от
серверного потока клиентскому:
на клиенте срабатывает следующий код
   var
    Buf : string;
   
   if Stream.WaitForData(40000) then
     begin
       SetLength(Buf, 18);
       nRead := Stream.Read(Buf[1], 18);
   ...
   end;
   
    Так вот на некоторых машинах, точнее на 2-х из 5-ти, в nRead
    возвращается 0! Но данные на самом деле передаются! На этих 2-х
    установлена Win98 SE, на остальных 3-х машинах, где в nRead
    возвращается количество принятых байт:
    1 - WinXP
    2 - WinXP
    3 - Win98 SE

   Я уже не знаю где искать, замена файлов
   winsock.dll,wsock32.dll,wininet.dll ни к чему не приводит.


slgeo   (2004-03-19 14:13:00) [21]

> Verg
нет, это самый первый Read в обработчике


Verg   (2004-03-19 14:07:00) [22]


> [29] slgeo   (19.03.04 13:41)
> > Verg
> А убедился я поставив в итоге на эту конкретную машину Delphi
> и увидев под отладчиком значение переменной nRead = 0, причем
> данные (а именно команда "UPDATE!0013433220!") были прочитаны
> в буфер
!


Или были и до Read?


Digitman   (2004-03-19 13:55:00) [23]

мне вообще непонятно, на кой шут в дан.случае транслировать что бы то ни было в текстовом формате..

что такое "256" в [9] ? откуда взялось это число ?

твой ПИО предусматривает трансляцию префикса/постфикса ? его длина что, всегда равна 256 байт ?


slgeo   (2004-03-19 13:55:00) [24]

procedure TDbServerThread.ClientExecute;
var
 Stream: TWinSocketStream;
 FileSize : Integer;
 strfile : string;
begin
 Stream := TWinSocketStream.Create(ClientSocket, 30000);
 try
   while not Terminated and ClientSocket.Connected do
   strfile := CurDir+ 'update.txt';
   if FileExists (strFile) then
   begin
     FileSize := FileUtil.GetFileSize(strfile);
     strFeedback := 'UPDATE!'+ AddChar('0',IntToStr(FileSize),10)+'!';
     ClientSocket.SendText(strFeedback);
     ClientSocket.SendStream(TMyFileStream.Create (
       strFile, fmOpenRead or fmShareDenyWrite));
     ClientSocket.SendText('000000!');
   end;
 finally
   Stream.Free;
 end;
end;

function TMyFileStream.Read(var Buffer; Count: Integer): Longint;
begin
result:=inherited Read(Buffer, Count);
// Form1.Gauge2.AddProgress(Count);
end;


Digitman   (2004-03-19 13:48:00) [25]

с учетом деталей происходящего в [29] есть большое подозрение, что строчка

TMyFileStream.Create (strFile, fmOpenRead or fmShareDenyWrite)

вызвала исключение, в рез-те чего соединение на передающей стороне было закрыто тем или иным образом, что и явилось причиной Eof на принимающей стороне


Digitman   (2004-03-19 13:42:00) [26]


> slgeo   (19.03.04 13:35) [28]


приводи ПОЛНЫЙ текст ClientExecute


slgeo   (2004-03-19 13:41:00) [27]

> Verg
А убедился я поставив в итоге на эту конкретную машину Delphi и увидев под отладчиком значение переменной nRead = 0, причем данные (а именно команда "UPDATE!0013433220!") были прочитаны в буфер!


slgeo   (2004-03-19 13:35:00) [28]

так, начнем сначала:
и приемная и передающая сторона используют TWinSocketStream,
в нашем случае передающая сторона TServerClientThread, а именно сервер обрабатывающий запросы от нескольких клиентов. ПОэтому приведенный выше код [22] возможно ввел немного в заблудение. Этот код находится внутри метода ClientExecute экземпляра TServerClientThread.


Verg   (2004-03-19 13:28:00) [29]


> [20] slgeo   (19.03.04 12:43)
> >Verg
> Ну а почему nRead всегда 0!!!


Когда "всегда"? Что значит "всегда"?
Не верю. Ты же вот не говоришь - как именно ты убедился, что ВСЕГДА 0.

Или ты чего-то не договариваешь или у тебя "поврежденная" Винда (что крайне маловероятно).

Ты же должен понимать, что "чудес" не бывает.


Digitman   (2004-03-19 13:20:00) [30]


> я думаю это вполне само собой разумеющееся


с чего бы "разумеющееся" ? режим одной стороны соединения не имеет никакого отношения к режиму другой стороны

вопрос здесь иной : а чем обосновано применение TWinSocketStream
на принимающей стороне и неприменение его же на передающей ? есть разумные доводы в пользу этой "солянки сборной" ?


slgeo   (2004-03-19 13:11:00) [31]

я думаю это вполне само собой разумеющееся, обе стороны работают в блокирующем режиме


Digitman   (2004-03-19 13:05:00) [32]


> slgeo


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

это крайне важно !!


slgeo   (2004-03-19 13:01:00) [33]

function TMyFileStream.Read(var Buffer; Count: Integer): Longint;
begin
result:=inherited Read(Buffer, Count);
Form1.Gauge2.AddProgress(Count);
end;


slgeo   (2004-03-19 12:58:00) [34]

FileSize := FileUtil.GetFileSize(strfile);
     //передаем команду на обновление с размером файла
     strFeedback := 'UPDATE!'+ AddChar('0',IntToStr (FileSize),10)+'!';
     ClientSocket.SendText(strFeedback);
     ClientSocket.SendStream(TMyFileStream.Create (
       strFile, fmOpenRead or fmShareDenyWrite));
     ClientSocket.SendText('000000!');


Digitman   (2004-03-19 12:54:00) [35]


> slgeo


приводи код кл.стороны
следы проблемы ведут туда


slgeo   (2004-03-19 12:43:00) [36]

>Verg
Ну а почему nRead всегда0!!!


Digitman   (2004-03-19 12:03:00) [37]


> Verg ©   (19.03.04 11:26) [16]


проанализировал ..
согласен, просигналит .. я был не прав


Verg   (2004-03-19 11:44:00) [38]

Этот код, при определенном размере передаваемого потока может не обнаружить признак конца твоего "файла" и будет продолжать ждать данные от собеседника. А тот, отправив все данные и признак конца 00000! просто закроет соединение.
Вот у тебя и nRead выскочит с нулем.


Verg   (2004-03-19 11:36:00) [39]


> [9] slgeo   (19.03.04 10:43)


Не знаю, прямо что и сказать - то один код показываешь, то другой.
Вот в последнем - почему ты так уверен, что признак конца (000000!) не попдет на границе принимаемых блоков?
Где гарантия, что ты его (эту последовательность) обнаружишь целикомв одном эелементарном буфере примема (256 байт)?


Verg   (2004-03-19 11:26:00) [40]


> предположим, из запрошенных 18 байт на момент анализа ивента
> в файловом потоке ввода доступно всего 9 байт ... разумеется,
> ивент не просигналил еще !


Ивент просигналит, именно просигналит, если в сокете есть хоть сколько-нибудь принятых байтов, хоть один!
Либо произошел разрыв петли, тогда getoverlappedresult вернет 0.


Страницы:   1 2 3

Наверх

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