Форум: "Сети";
Текущий архив: 2004.04.11;
Скачать: [xml.tar.bz2];
ВнизНе возвращается количество полученных байт в блокирующисокетах??? Найти похожие ветки
← →
slgeo (2004-03-19 10:04) [0]У меня идет обмен по блокирующим сокетам, а точнее передача файла от
серверного потока клиентскому:
на клиенте срабатывает следующий код
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 10:04) [0]У меня идет обмен по блокирующим сокетам, а точнее передача файла от
серверного потока клиентскому:
на клиенте срабатывает следующий код
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 ни к чему не приводит.
← →
Verg © (2004-03-19 10:10) [1]nRead =0 в данном случае означает, что соединение было закрыто.
← →
Verg © (2004-03-19 10:10) [1]nRead =0 в данном случае означает, что соединение было закрыто.
← →
Digitman © (2004-03-19 10:12) [2]
> У меня идет обмен по блокирующим сокетам
ничего подобного
у тебя обмен идет с использованием НЕблокирующего режима
так что тот результат, что ты получаешь - вполне ожидаем
← →
Digitman © (2004-03-19 10:12) [2]
> У меня идет обмен по блокирующим сокетам
ничего подобного
у тебя обмен идет с использованием НЕблокирующего режима
так что тот результат, что ты получаешь - вполне ожидаем
← →
Digitman © (2004-03-19 10:15) [3]
> Verg © (19.03.04 10:10) [1]
уверен ?
if FEvent.WaitFor(FTimeOut) <> wrSignaled then //нет данных в буфере приема
Result := 0
else
begin
GetOverlappedResult(FSocket.SocketHandle, Overlapped, DWORD(Result), False);
FEvent.ResetEvent;
end;
← →
Digitman © (2004-03-19 10:15) [3]
> Verg © (19.03.04 10:10) [1]
уверен ?
if FEvent.WaitFor(FTimeOut) <> wrSignaled then //нет данных в буфере приема
Result := 0
else
begin
GetOverlappedResult(FSocket.SocketHandle, Overlapped, DWORD(Result), False);
FEvent.ResetEvent;
end;
← →
slgeo (2004-03-19 10:19) [4]to Digitman
с чего вдруг???
OptClientThread = class(TThread)
private
ClientSocket: TClientSocket;
...
end;
procedure OptClientThread.Execute;
var
nRead: Integer;
Stream: TWinSocketStream;
try
ClientSocket := TClientSocket.Create (nil);
Stream := nil;
try
ClientSocket.Address := ServerAddress;
ClientSocket.ClientType := ctBlocking;
ClientSocket.Port := RemotePort;
ClientSocket.Active := True;
Stream := TWinSocketStream.Create(ClientSocket.Socket, 30000);
...
except
....
end;
← →
slgeo (2004-03-19 10:19) [4]to Digitman
с чего вдруг???
OptClientThread = class(TThread)
private
ClientSocket: TClientSocket;
...
end;
procedure OptClientThread.Execute;
var
nRead: Integer;
Stream: TWinSocketStream;
try
ClientSocket := TClientSocket.Create (nil);
Stream := nil;
try
ClientSocket.Address := ServerAddress;
ClientSocket.ClientType := ctBlocking;
ClientSocket.Port := RemotePort;
ClientSocket.Active := True;
Stream := TWinSocketStream.Create(ClientSocket.Socket, 30000);
...
except
....
end;
← →
Verg © (2004-03-19 10:25) [5]Если это сработало (вернуло true)
> if Stream.WaitForData(40000) then
значит в сокете сработал ReadFDS, а это в свою очередь означает, что у сокета во входном потоке что-то появилось. Это могут быть данные, а может быть и признак конца файла ( Read() вернет 0 )
> [2] Digitman © (19.03.04 10:12)
А с каким еще сокетом может работать TWinSocketStream, у которого есть метод WaitForData?
← →
Verg © (2004-03-19 10:25) [5]Если это сработало (вернуло true)
> if Stream.WaitForData(40000) then
значит в сокете сработал ReadFDS, а это в свою очередь означает, что у сокета во входном потоке что-то появилось. Это могут быть данные, а может быть и признак конца файла ( Read() вернет 0 )
> [2] Digitman © (19.03.04 10:12)
А с каким еще сокетом может работать TWinSocketStream, у которого есть метод WaitForData?
← →
slgeo (2004-03-19 10:32) [6]>Verg
во-во это уже ближе, в Buf попадает что-то типа PK.... (если я не ошибаюсь это действительно признак конца файла). Но ведь с другой стороны был передан файл??? Куда он пропал?
Кстати выше по коду перед приемом файла у меня есть еще прием команды. Так вот в nRead снова 0, но в Buf данные попадают!!!
← →
slgeo (2004-03-19 10:32) [6]>Verg
во-во это уже ближе, в Buf попадает что-то типа PK.... (если я не ошибаюсь это действительно признак конца файла). Но ведь с другой стороны был передан файл??? Куда он пропал?
Кстати выше по коду перед приемом файла у меня есть еще прием команды. Так вот в nRead снова 0, но в Buf данные попадают!!!
← →
Digitman © (2004-03-19 10:36) [7]при использовании TWinSocketStream.Read запускается асинхронная overlapped-операция ввода
блокирование вызывающего код.потока происходит здесь
if FEvent.WaitFor(FTimeOut) <> wrSignaled then
а здесь - неблокирующая операция ввода
if not ReadFile(FSocket.SocketHandle, Buffer, Count, DWORD(Result),
@Overlapped) and (GetLastError <> ERROR_IO_PENDING) then
begin
ErrorCode := GetLastError;
raise ESocketError.CreateResFmt(@sSocketIOError, [sSocketRead, ErrorCode,
SysErrorMessage(ErrorCode)]);
end;
← →
Digitman © (2004-03-19 10:36) [7]при использовании TWinSocketStream.Read запускается асинхронная overlapped-операция ввода
блокирование вызывающего код.потока происходит здесь
if FEvent.WaitFor(FTimeOut) <> wrSignaled then
а здесь - неблокирующая операция ввода
if not ReadFile(FSocket.SocketHandle, Buffer, Count, DWORD(Result),
@Overlapped) and (GetLastError <> ERROR_IO_PENDING) then
begin
ErrorCode := GetLastError;
raise ESocketError.CreateResFmt(@sSocketIOError, [sSocketRead, ErrorCode,
SysErrorMessage(ErrorCode)]);
end;
← →
Verg © (2004-03-19 10:37) [8]Я там не вижу никакого "приема файла". Я там вижу ожидание появления данных в сокете и попытку проичтать из него не более 18-ти байтов в строку.
Какой файл? Где файл?
← →
Verg © (2004-03-19 10:37) [8]Я там не вижу никакого "приема файла". Я там вижу ожидание появления данных в сокете и попытку проичтать из него не более 18-ти байтов в строку.
Какой файл? Где файл?
← →
slgeo (2004-03-19 10:43) [9]вот так точнее
var
ms : TMemoryStream;
if Stream.WaitForData(60000) then
begin
Buf := "";
SetLength(Buf, 256);
FMaxProgress := fsize;
Synchronize(DoMaxProgress);
while True do
begin
nRead := Stream.Read(Buf[1],256);
if Pos("000000!",Buf)>0 then
begin
StrIn := Copy(Buf,1,Pos("000000!",Buf)-1);
ms.Write (strIn[1], Length(strIn));
FMaxProgress := 0;
Synchronize(DoMaxProgress);
Break;
end
else
ms.Write(Buf[1], nRead);
end;
end else
begin
FLogMsg := "Не получен очередной пакет обновления!!!";
Synchronize(DoLog);
Exit;
end;
← →
slgeo (2004-03-19 10:43) [9]вот так точнее
var
ms : TMemoryStream;
if Stream.WaitForData(60000) then
begin
Buf := "";
SetLength(Buf, 256);
FMaxProgress := fsize;
Synchronize(DoMaxProgress);
while True do
begin
nRead := Stream.Read(Buf[1],256);
if Pos("000000!",Buf)>0 then
begin
StrIn := Copy(Buf,1,Pos("000000!",Buf)-1);
ms.Write (strIn[1], Length(strIn));
FMaxProgress := 0;
Synchronize(DoMaxProgress);
Break;
end
else
ms.Write(Buf[1], nRead);
end;
end else
begin
FLogMsg := "Не получен очередной пакет обновления!!!";
Synchronize(DoLog);
Exit;
end;
← →
slgeo (2004-03-19 10:44) [10]и дальше естесвенно
ms.Position := 0;
ms.SaveToFile(ExtractFilePath(Application.ExeName)"+"update.txt");
ms.Free;
← →
slgeo (2004-03-19 10:44) [10]и дальше естесвенно
ms.Position := 0;
ms.SaveToFile(ExtractFilePath(Application.ExeName)"+"update.txt");
ms.Free;
← →
Digitman © (2004-03-19 10:52) [11]
> Verg © (19.03.04 10:25) [5]
да, я здесь был неточен
гнездо-то само по себе иниц-но для работы в блок.режиме, но работа с ним идет с использованием файлового overlapped-ввода/вывода, что само по себе подразумевает неблок.режим ввода/вывода
> slgeo
вот цитата :
The event specified in the OVERLAPPED structure is set to the signaled state upon completion of the read operation.
это означает, что сигнал ивента следует ожидать только ПОСЛЕ приема и доступности в файловом буфере тех самых запрошенных тобой 18-ти байт
если же ивент не просигналил за 30 секунд (ты сам обозначил это время), то, как видишь из исх.текста, метод Read вернет тебе 0 .. т.е. какая-то часть запрошенных к чтению данных успела прийти за это время, а какая-то еще "в пути"... очевидно, что следует циклически повторять вызов метода Read() до тех пор, пока не просигналит ивент либо не будет возбуждено исключение по потенциально возможному разрыву транспортного канала
← →
Digitman © (2004-03-19 10:52) [11]
> Verg © (19.03.04 10:25) [5]
да, я здесь был неточен
гнездо-то само по себе иниц-но для работы в блок.режиме, но работа с ним идет с использованием файлового overlapped-ввода/вывода, что само по себе подразумевает неблок.режим ввода/вывода
> slgeo
вот цитата :
The event specified in the OVERLAPPED structure is set to the signaled state upon completion of the read operation.
это означает, что сигнал ивента следует ожидать только ПОСЛЕ приема и доступности в файловом буфере тех самых запрошенных тобой 18-ти байт
если же ивент не просигналил за 30 секунд (ты сам обозначил это время), то, как видишь из исх.текста, метод Read вернет тебе 0 .. т.е. какая-то часть запрошенных к чтению данных успела прийти за это время, а какая-то еще "в пути"... очевидно, что следует циклически повторять вызов метода Read() до тех пор, пока не просигналит ивент либо не будет возбуждено исключение по потенциально возможному разрыву транспортного канала
← →
Verg © (2004-03-19 10:55) [12]2 Digitman
> if FEvent.WaitFor(FTimeOut) <> wrSignaled then //нет
> данных в буфере приема
> Result := 0
Вот это есть некая "кривость". Потому как в результате невозможно отличить ситуацию таймаута от ситуации EOF (разрыв соединения собеседником).
Хоть бы -1 присвоили что-ли...
Сокет тем временем именно в блокирующем режиме. А для того, чтобы обеспечить возможность таймаута при чтении там воспользовались Overlapped IO с блокировкаой WaitForSingleObject (хотя можно было бы и select+recv-ом также все сделать).
Т.о. метод Read этого TWinSocketStream блокирующий по сути своей. Т.е. он не вернет управление потоку до тех пор, пока операция не закончится хоть с каким-то результатом.
← →
Verg © (2004-03-19 10:55) [12]2 Digitman
> if FEvent.WaitFor(FTimeOut) <> wrSignaled then //нет
> данных в буфере приема
> Result := 0
Вот это есть некая "кривость". Потому как в результате невозможно отличить ситуацию таймаута от ситуации EOF (разрыв соединения собеседником).
Хоть бы -1 присвоили что-ли...
Сокет тем временем именно в блокирующем режиме. А для того, чтобы обеспечить возможность таймаута при чтении там воспользовались Overlapped IO с блокировкаой WaitForSingleObject (хотя можно было бы и select+recv-ом также все сделать).
Т.о. метод Read этого TWinSocketStream блокирующий по сути своей. Т.е. он не вернет управление потоку до тех пор, пока операция не закончится хоть с каким-то результатом.
← →
Verg © (2004-03-19 10:59) [13]
> успела прийти за это время, а какая-то еще "в пути"... очевидно,
> что следует циклически повторять вызов метода Read() до
> тех пор, пока не просигналит ивент либо не будет возбуждено
> исключение по потенциально возможному разрыву транспортного
> канала
Нет, ты забыл что ли, что waitfordata уже сработал, т.е. в приемном буфере сокета уже что-то должно быть - хоть данные, хоть EOF
← →
Verg © (2004-03-19 10:59) [13]
> успела прийти за это время, а какая-то еще "в пути"... очевидно,
> что следует циклически повторять вызов метода Read() до
> тех пор, пока не просигналит ивент либо не будет возбуждено
> исключение по потенциально возможному разрыву транспортного
> канала
Нет, ты забыл что ли, что waitfordata уже сработал, т.е. в приемном буфере сокета уже что-то должно быть - хоть данные, хоть EOF
← →
Digitman © (2004-03-19 11:11) [14]
> Verg © (19.03.04 10:59) [13]
а waitfordata-то здесь причем ? он не имеет отношения ни к overlapped-операции ввода ни к ивенту ..
ну да, ну вернул он True, что-то там в приехало ..
теперь мы стартуем/рестартуем собственно overlapped-операцию (неблокирующую по определению), после чего тут же анализируем сигнал ивента .. предположим, из запрошенных 18 байт на момент анализа ивента в файловом потоке ввода доступно всего 9 байт ... разумеется, ивент не просигналил еще ! ... а раз не просигналил, то и Result = 0...
ну и иная ситуация (та на которую ты намекаешь) - ивент просигналил, но в файловом потоке есть EOF ... тогда Read() вернет из overlapped-структуры то число байт, что находится в файловом потоке ДО Eof ... и вполне возможно, что до EOF ничего и не приходило ... тогда ситуация с Result = 0 так же объяснима
← →
Digitman © (2004-03-19 11:11) [14]
> Verg © (19.03.04 10:59) [13]
а waitfordata-то здесь причем ? он не имеет отношения ни к overlapped-операции ввода ни к ивенту ..
ну да, ну вернул он True, что-то там в приехало ..
теперь мы стартуем/рестартуем собственно overlapped-операцию (неблокирующую по определению), после чего тут же анализируем сигнал ивента .. предположим, из запрошенных 18 байт на момент анализа ивента в файловом потоке ввода доступно всего 9 байт ... разумеется, ивент не просигналил еще ! ... а раз не просигналил, то и Result = 0...
ну и иная ситуация (та на которую ты намекаешь) - ивент просигналил, но в файловом потоке есть EOF ... тогда Read() вернет из overlapped-структуры то число байт, что находится в файловом потоке ДО Eof ... и вполне возможно, что до EOF ничего и не приходило ... тогда ситуация с Result = 0 так же объяснима
← →
Digitman © (2004-03-19 11:18) [15]
> Verg © (19.03.04 10:55) [12]
нет, ну насчет того, что Read() сам по себе блокирующий, я согласен на все 100 ...
я имел ввиду саму операцию ввода/вывода, что задействуется внутри Read()
согласен - реализовали это метод крайне криво, посему лично я класс TWinSocketStream никогда не использую и другим категорически не рекомендую
← →
Digitman © (2004-03-19 11:18) [15]
> Verg © (19.03.04 10:55) [12]
нет, ну насчет того, что Read() сам по себе блокирующий, я согласен на все 100 ...
я имел ввиду саму операцию ввода/вывода, что задействуется внутри Read()
согласен - реализовали это метод крайне криво, посему лично я класс TWinSocketStream никогда не использую и другим категорически не рекомендую
← →
Verg © (2004-03-19 11:26) [16]
> предположим, из запрошенных 18 байт на момент анализа ивента
> в файловом потоке ввода доступно всего 9 байт ... разумеется,
> ивент не просигналил еще !
Ивент просигналит, именно просигналит, если в сокете есть хоть сколько-нибудь принятых байтов, хоть один!
Либо произошел разрыв петли, тогда getoverlappedresult вернет 0.
← →
Verg © (2004-03-19 11:26) [16]
> предположим, из запрошенных 18 байт на момент анализа ивента
> в файловом потоке ввода доступно всего 9 байт ... разумеется,
> ивент не просигналил еще !
Ивент просигналит, именно просигналит, если в сокете есть хоть сколько-нибудь принятых байтов, хоть один!
Либо произошел разрыв петли, тогда getoverlappedresult вернет 0.
← →
Verg © (2004-03-19 11:36) [17]
> [9] slgeo (19.03.04 10:43)
Не знаю, прямо что и сказать - то один код показываешь, то другой.
Вот в последнем - почему ты так уверен, что признак конца (000000!) не попдет на границе принимаемых блоков?
Где гарантия, что ты его (эту последовательность) обнаружишь целиком в одном эелементарном буфере примема (256 байт)?
← →
Verg © (2004-03-19 11:36) [17]
> [9] slgeo (19.03.04 10:43)
Не знаю, прямо что и сказать - то один код показываешь, то другой.
Вот в последнем - почему ты так уверен, что признак конца (000000!) не попдет на границе принимаемых блоков?
Где гарантия, что ты его (эту последовательность) обнаружишь целиком в одном эелементарном буфере примема (256 байт)?
← →
Verg © (2004-03-19 11:44) [18]Этот код, при определенном размере передаваемого потока может не обнаружить признак конца твоего "файла" и будет продолжать ждать данные от собеседника. А тот, отправив все данные и признак конца 00000! просто закроет соединение.
Вот у тебя и nRead выскочит с нулем.
← →
Verg © (2004-03-19 11:44) [18]Этот код, при определенном размере передаваемого потока может не обнаружить признак конца твоего "файла" и будет продолжать ждать данные от собеседника. А тот, отправив все данные и признак конца 00000! просто закроет соединение.
Вот у тебя и nRead выскочит с нулем.
← →
Digitman © (2004-03-19 12:03) [19]
> Verg © (19.03.04 11:26) [16]
проанализировал ..
согласен, просигналит .. я был не прав
← →
Digitman © (2004-03-19 12:03) [19]
> Verg © (19.03.04 11:26) [16]
проанализировал ..
согласен, просигналит .. я был не прав
← →
slgeo (2004-03-19 12:43) [20]>Verg
Ну а почему nRead всегда 0!!!
← →
slgeo (2004-03-19 12:43) [20]>Verg
Ну а почему nRead всегда 0!!!
← →
Digitman © (2004-03-19 12:54) [21]
> slgeo
приводи код кл.стороны
следы проблемы ведут туда
← →
Digitman © (2004-03-19 12:54) [21]
> slgeo
приводи код кл.стороны
следы проблемы ведут туда
← →
slgeo (2004-03-19 12:58) [22]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!");
← →
slgeo (2004-03-19 12:58) [22]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!");
← →
slgeo (2004-03-19 13:01) [23]function TMyFileStream.Read(var Buffer; Count: Integer): Longint;
begin
result:=inherited Read(Buffer, Count);
Form1.Gauge2.AddProgress(Count);
end;
← →
slgeo (2004-03-19 13:01) [23]function TMyFileStream.Read(var Buffer; Count: Integer): Longint;
begin
result:=inherited Read(Buffer, Count);
Form1.Gauge2.AddProgress(Count);
end;
← →
Digitman © (2004-03-19 13:05) [24]
> slgeo
почему ты, явно заострив внимание на блок.режиме принимающей стороны, ни словом не обмолвился о режиме передающей ?
это крайне важно !!
← →
Digitman © (2004-03-19 13:05) [24]
> slgeo
почему ты, явно заострив внимание на блок.режиме принимающей стороны, ни словом не обмолвился о режиме передающей ?
это крайне важно !!
← →
slgeo (2004-03-19 13:11) [25]я думаю это вполне само собой разумеющееся, обе стороны работают в блокирующем режиме
← →
slgeo (2004-03-19 13:11) [25]я думаю это вполне само собой разумеющееся, обе стороны работают в блокирующем режиме
← →
Digitman © (2004-03-19 13:20) [26]
> я думаю это вполне само собой разумеющееся
с чего бы "разумеющееся" ? режим одной стороны соединения не имеет никакого отношения к режиму другой стороны
вопрос здесь иной : а чем обосновано применение TWinSocketStream
на принимающей стороне и неприменение его же на передающей ? есть разумные доводы в пользу этой "солянки сборной" ?
← →
Digitman © (2004-03-19 13:20) [26]
> я думаю это вполне само собой разумеющееся
с чего бы "разумеющееся" ? режим одной стороны соединения не имеет никакого отношения к режиму другой стороны
вопрос здесь иной : а чем обосновано применение TWinSocketStream
на принимающей стороне и неприменение его же на передающей ? есть разумные доводы в пользу этой "солянки сборной" ?
← →
Verg © (2004-03-19 13:28) [27]
> [20] slgeo (19.03.04 12:43)
> >Verg
> Ну а почему nRead всегда 0!!!
Когда "всегда"? Что значит "всегда"?
Не верю. Ты же вот не говоришь - как именно ты убедился, что ВСЕГДА 0.
Или ты чего-то не договариваешь или у тебя "поврежденная" Винда (что крайне маловероятно).
Ты же должен понимать, что "чудес" не бывает.
← →
Verg © (2004-03-19 13:28) [27]
> [20] slgeo (19.03.04 12:43)
> >Verg
> Ну а почему nRead всегда 0!!!
Когда "всегда"? Что значит "всегда"?
Не верю. Ты же вот не говоришь - как именно ты убедился, что ВСЕГДА 0.
Или ты чего-то не договариваешь или у тебя "поврежденная" Винда (что крайне маловероятно).
Ты же должен понимать, что "чудес" не бывает.
← →
slgeo (2004-03-19 13:35) [28]так, начнем сначала:
и приемная и передающая сторона используют TWinSocketStream,
в нашем случае передающая сторона TServerClientThread, а именно сервер обрабатывающий запросы от нескольких клиентов. ПОэтому приведенный выше код [22] возможно ввел немного в заблудение. Этот код находится внутри метода ClientExecute экземпляра TServerClientThread.
← →
slgeo (2004-03-19 13:35) [28]так, начнем сначала:
и приемная и передающая сторона используют TWinSocketStream,
в нашем случае передающая сторона TServerClientThread, а именно сервер обрабатывающий запросы от нескольких клиентов. ПОэтому приведенный выше код [22] возможно ввел немного в заблудение. Этот код находится внутри метода ClientExecute экземпляра TServerClientThread.
← →
slgeo (2004-03-19 13:41) [29]> Verg
А убедился я поставив в итоге на эту конкретную машину Delphi и увидев под отладчиком значение переменной nRead = 0, причем данные (а именно команда "UPDATE!0013433220!") были прочитаны в буфер!
← →
slgeo (2004-03-19 13:41) [29]> Verg
А убедился я поставив в итоге на эту конкретную машину Delphi и увидев под отладчиком значение переменной nRead = 0, причем данные (а именно команда "UPDATE!0013433220!") были прочитаны в буфер!
← →
Digitman © (2004-03-19 13:42) [30]
> slgeo (19.03.04 13:35) [28]
приводи ПОЛНЫЙ текст ClientExecute
← →
Digitman © (2004-03-19 13:42) [30]
> slgeo (19.03.04 13:35) [28]
приводи ПОЛНЫЙ текст ClientExecute
← →
Digitman © (2004-03-19 13:48) [31]с учетом деталей происходящего в [29] есть большое подозрение, что строчка
TMyFileStream.Create (strFile, fmOpenRead or fmShareDenyWrite)
вызвала исключение, в рез-те чего соединение на передающей стороне было закрыто тем или иным образом, что и явилось причиной Eof на принимающей стороне
← →
Digitman © (2004-03-19 13:48) [31]с учетом деталей происходящего в [29] есть большое подозрение, что строчка
TMyFileStream.Create (strFile, fmOpenRead or fmShareDenyWrite)
вызвала исключение, в рез-те чего соединение на передающей стороне было закрыто тем или иным образом, что и явилось причиной Eof на принимающей стороне
← →
slgeo (2004-03-19 13:55) [32]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;
← →
slgeo (2004-03-19 13:55) [32]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:55) [33]мне вообще непонятно, на кой шут в дан.случае транслировать что бы то ни было в текстовом формате..
что такое "256" в [9] ? откуда взялось это число ?
твой ПИО предусматривает трансляцию префикса/постфикса ? его длина что, всегда равна 256 байт ?
← →
Digitman © (2004-03-19 13:55) [33]мне вообще непонятно, на кой шут в дан.случае транслировать что бы то ни было в текстовом формате..
что такое "256" в [9] ? откуда взялось это число ?
твой ПИО предусматривает трансляцию префикса/постфикса ? его длина что, всегда равна 256 байт ?
← →
Verg © (2004-03-19 14:07) [34]
> [29] slgeo (19.03.04 13:41)
> > Verg
> А убедился я поставив в итоге на эту конкретную машину Delphi
> и увидев под отладчиком значение переменной nRead = 0, причем
> данные (а именно команда "UPDATE!0013433220!") были прочитаны
> в буфер!
Или были и до Read?
← →
Verg © (2004-03-19 14:07) [34]
> [29] slgeo (19.03.04 13:41)
> > Verg
> А убедился я поставив в итоге на эту конкретную машину Delphi
> и увидев под отладчиком значение переменной nRead = 0, причем
> данные (а именно команда "UPDATE!0013433220!") были прочитаны
> в буфер!
Или были и до Read?
← →
slgeo (2004-03-19 14:13) [35]> Verg
нет, это самый первый Read в обработчике
← →
slgeo (2004-03-19 14:13) [35]> Verg
нет, это самый первый Read в обработчике
← →
Verg © (2004-03-19 14:25) [36]
> [35] slgeo (19.03.04 14:13)
В обработчике чего? Ну и что, что "первый"?
Слушай, ну сколько можно из тебя "клещами"-то все вытаскивать?
Read всегда возвращает истинное положение дел в сокете.
Если он сказал, что ноль байтов принял, значит так оно и есть.
Не веришь?
Я проверял многократно (мягко говоря:) ) - все так и есть.
Если у тебя порежденный драйвер TCP/IP на машине, то это должно сказаться и на других приложениях, работающих через сокеты (через WinSock).
← →
Verg © (2004-03-19 14:25) [36]
> [35] slgeo (19.03.04 14:13)
В обработчике чего? Ну и что, что "первый"?
Слушай, ну сколько можно из тебя "клещами"-то все вытаскивать?
Read всегда возвращает истинное положение дел в сокете.
Если он сказал, что ноль байтов принял, значит так оно и есть.
Не веришь?
Я проверял многократно (мягко говоря:) ) - все так и есть.
Если у тебя порежденный драйвер TCP/IP на машине, то это должно сказаться и на других приложениях, работающих через сокеты (через WinSock).
← →
slgeo (2004-03-19 14:39) [37]вот практически вся процедура принимающей стороны
procedure OptClientThread.Execute;
var
I, nRead: Integer;
Stream: TWinSocketStream;
ms : TMemoryStream;
Buf, StrIn : String;
fsize : integer;
strFile : string;
FileSize : integer;
begin
try
ClientSocket := TClientSocket.Create (nil);
Stream := nil;
try
ClientSocket.Address := ServerAddress;
ClientSocket.ClientType := ctBlocking;
ClientSocket.Port := RemotePort;
ClientSocket.Active := True;
Stream := TWinSocketStream.Create(ClientSocket.Socket, 30000);
except
FLogMsg := "Нет соединения с сервером! Повторите обновление позднее!";
Synchronize(DoLog);
Exit;
end;
FLogMsg := "Отправляем запрос на обновление...";
Synchronize(DoLog);
dmData.IBSQL.Close;
dmData.IBSQL.SQL.Text := "select sendstatus from settings";
dmData.IBSQL.ExecQuery;
ClientSocket.Socket.SendText ("UPD_"+IntToStr(UIN)+"_"+dmData.IBSQL.Fields[0].AsString+"!");
if Stream.WaitForData(50000) then
begin
Buf := "";
SetLength(Buf, 18);
nRead := Stream.Read(Buf[1], 18);
// SetLength(Buf, nRead); если убрать комментарий то Buf очищается
if POS("UPDATE!",Buf)=1 then
begin
ssize := Copy (Buf, 8, 10);
try
fsize := StrToInt(ssize);
except
fsize := 0;
end;
end
end else
begin
FLogMsg := "Нет ответа на запрос обновления!!!";
Synchronize(DoLog);
Exit;
end;
//получение пакета обновления
DeleteFile(ExtractFilePath(Application.ExeName)+"update.txt");
ms := TMemoryStream.Create;
FLogMsg := "Загружаем данные...";
if Stream.WaitForData(60000) then
begin
Buf := "";
SetLength(Buf, 256);
FMaxProgress := fsize;
Synchronize(DoMaxProgress);
while True do
begin
nRead := Stream.Read(Buf[1],256);
if Pos("000000!",Buf)>0 then
begin
StrIn := Copy(Buffer,1,Pos("000000!",Buf)-1);
ms.Write (strIn[1], Length(strIn));
FMaxProgress := 0;
Synchronize(DoMaxProgress);
Break;
end
else
begin
ms.Write(Buf[1], nRead);
FProgress := nRead;
Synchronize(DoProgress);
end;
end;
end else
begin
FLogMsg := "Не получен очередной пакет обновления!!!";
Synchronize(DoLog);
Exit;
end;
FLogMsg := "Загрузка завершена!!!";
Synchronize(DoLog);
ms.Position := 0;
ms.SaveToFile(ExtractFilePath(Application.ExeName)+"inbox\"+"update.zip");
ms.Free;
.....
except
....
end;
end;
← →
slgeo (2004-03-19 14:39) [37]вот практически вся процедура принимающей стороны
procedure OptClientThread.Execute;
var
I, nRead: Integer;
Stream: TWinSocketStream;
ms : TMemoryStream;
Buf, StrIn : String;
fsize : integer;
strFile : string;
FileSize : integer;
begin
try
ClientSocket := TClientSocket.Create (nil);
Stream := nil;
try
ClientSocket.Address := ServerAddress;
ClientSocket.ClientType := ctBlocking;
ClientSocket.Port := RemotePort;
ClientSocket.Active := True;
Stream := TWinSocketStream.Create(ClientSocket.Socket, 30000);
except
FLogMsg := "Нет соединения с сервером! Повторите обновление позднее!";
Synchronize(DoLog);
Exit;
end;
FLogMsg := "Отправляем запрос на обновление...";
Synchronize(DoLog);
dmData.IBSQL.Close;
dmData.IBSQL.SQL.Text := "select sendstatus from settings";
dmData.IBSQL.ExecQuery;
ClientSocket.Socket.SendText ("UPD_"+IntToStr(UIN)+"_"+dmData.IBSQL.Fields[0].AsString+"!");
if Stream.WaitForData(50000) then
begin
Buf := "";
SetLength(Buf, 18);
nRead := Stream.Read(Buf[1], 18);
// SetLength(Buf, nRead); если убрать комментарий то Buf очищается
if POS("UPDATE!",Buf)=1 then
begin
ssize := Copy (Buf, 8, 10);
try
fsize := StrToInt(ssize);
except
fsize := 0;
end;
end
end else
begin
FLogMsg := "Нет ответа на запрос обновления!!!";
Synchronize(DoLog);
Exit;
end;
//получение пакета обновления
DeleteFile(ExtractFilePath(Application.ExeName)+"update.txt");
ms := TMemoryStream.Create;
FLogMsg := "Загружаем данные...";
if Stream.WaitForData(60000) then
begin
Buf := "";
SetLength(Buf, 256);
FMaxProgress := fsize;
Synchronize(DoMaxProgress);
while True do
begin
nRead := Stream.Read(Buf[1],256);
if Pos("000000!",Buf)>0 then
begin
StrIn := Copy(Buffer,1,Pos("000000!",Buf)-1);
ms.Write (strIn[1], Length(strIn));
FMaxProgress := 0;
Synchronize(DoMaxProgress);
Break;
end
else
begin
ms.Write(Buf[1], nRead);
FProgress := nRead;
Synchronize(DoProgress);
end;
end;
end else
begin
FLogMsg := "Не получен очередной пакет обновления!!!";
Synchronize(DoLog);
Exit;
end;
FLogMsg := "Загрузка завершена!!!";
Synchronize(DoLog);
ms.Position := 0;
ms.SaveToFile(ExtractFilePath(Application.ExeName)+"inbox\"+"update.zip");
ms.Free;
.....
except
....
end;
end;
← →
Verg © (2004-03-19 15:28) [38]Еще раз говорю - значит сервер закрывает соединение (завершает клиентский поток). Возможно он неверно принимает запрос. Ищи там. Пусть сервер ведет лог.
Провеь настройки TCP/IP на "неработающей" машине.
Далее. Проверить надо что именно возвращает
if FEvent.WaitFor(FTimeOut) <> wrSignaled then
Result := 0
else
Если он возвращает не wrSignaled, то тут варанты:
TWaitResult = (wrSignaled, wrTimeout, wrAbandoned, wrError);
Если этого сделать не сможешь, то просто замени прием на
с nRead := Stream.Read(Buf[1], 18);
на
if Stream.WaitForData(30000) then
nRead := recv(ClientSocket.SocketHandle, buf[1], length(buf), 0);
else
nRead := SOCKET_ERROR-1;
Посмотри что скажет.
← →
Verg © (2004-03-19 15:28) [38]Еще раз говорю - значит сервер закрывает соединение (завершает клиентский поток). Возможно он неверно принимает запрос. Ищи там. Пусть сервер ведет лог.
Провеь настройки TCP/IP на "неработающей" машине.
Далее. Проверить надо что именно возвращает
if FEvent.WaitFor(FTimeOut) <> wrSignaled then
Result := 0
else
Если он возвращает не wrSignaled, то тут варанты:
TWaitResult = (wrSignaled, wrTimeout, wrAbandoned, wrError);
Если этого сделать не сможешь, то просто замени прием на
с nRead := Stream.Read(Buf[1], 18);
на
if Stream.WaitForData(30000) then
nRead := recv(ClientSocket.SocketHandle, buf[1], length(buf), 0);
else
nRead := SOCKET_ERROR-1;
Посмотри что скажет.
← →
slgeo (2004-03-19 16:29) [39]проверил
FEvent.WaitFor(FTimeOut) возвращает wrSignaled !
← →
slgeo (2004-03-19 16:29) [39]проверил
FEvent.WaitFor(FTimeOut) возвращает wrSignaled !
← →
Digitman © (2004-03-19 16:35) [40]
> slgeo
слухай сюда ...
при всем моем уважении к тебе, искренне пытающегося найти "первопричину", и к Андрею, искренне пытающегося наставить тебя на путь истинный (имея на о колоссальный практ. им теор. опыт), репу свою чесать по поводу "глюков" должен, в 1-ю очередь, именно ТЫ, и никто иной ...
и у тепя, мил мой, коль скоро ты пользуешь Делфи, под рукой всегда есть великолепный инструмент под названием Интегрированный Отладчик Делфи ... и какого шута ты им не пользуешься по сей момент - это для нас с Андреем и коллегами составляет великую гостайну ... в каковую (в тайности применения которого в поисках истины) без твоего высочайшего соизволения мы не имеем возможности "въехать"
← →
Digitman © (2004-03-19 16:35) [40]
> slgeo
слухай сюда ...
при всем моем уважении к тебе, искренне пытающегося найти "первопричину", и к Андрею, искренне пытающегося наставить тебя на путь истинный (имея на о колоссальный практ. им теор. опыт), репу свою чесать по поводу "глюков" должен, в 1-ю очередь, именно ТЫ, и никто иной ...
и у тепя, мил мой, коль скоро ты пользуешь Делфи, под рукой всегда есть великолепный инструмент под названием Интегрированный Отладчик Делфи ... и какого шута ты им не пользуешься по сей момент - это для нас с Андреем и коллегами составляет великую гостайну ... в каковую (в тайности применения которого в поисках истины) без твоего высочайшего соизволения мы не имеем возможности "въехать"
Страницы: 1 2 вся ветка
Форум: "Сети";
Текущий архив: 2004.04.11;
Скачать: [xml.tar.bz2];
Память: 0.72 MB
Время: 0.047 c