Текущий архив: 2004.04.11;
Скачать: CL | DM;
ВнизНе возвращается количество полученных байт в блокирующисокетах??? Найти похожие ветки
← →
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-ю очередь, именно ТЫ, и никто иной ...
и у тепя, мил мой, коль скоро ты пользуешь Делфи, под рукой всегда есть великолепный инструмент под названием Интегрированный Отладчик Делфи ... и какого шута ты им не пользуешься по сей момент - это для нас с Андреем и коллегами составляет великую гостайну ... в каковую (в тайности применения которого в поисках истины) без твоего высочайшего соизволения мы не имеем возможности "въехать"
← →
Digitman © (2004-03-19 16:36) [41]
> slgeo
слухай сюда ...
при всем моем уважении к тебе, искренне пытающегося найти "первопричину", и к Андрею, искренне пытающегося наставить тебя на путь истинный (имея на о колоссальный практ. им теор. опыт), репу свою чесать по поводу "глюков" должен, в 1-ю очередь, именно ТЫ, и никто иной ...
и у тепя, мил мой, коль скоро ты пользуешь Делфи, под рукой всегда есть великолепный инструмент под названием Интегрированный Отладчик Делфи ... и какого шута ты им не пользуешься по сей момент - это для нас с Андреем и коллегами составляет великую гостайну ... в каковую (в тайности применения которого в поисках истины) без твоего высочайшего соизволения мы не имеем возможности "въехать"
← →
Digitman © (2004-03-19 16:36) [41]
> slgeo
слухай сюда ...
при всем моем уважении к тебе, искренне пытающегося найти "первопричину", и к Андрею, искренне пытающегося наставить тебя на путь истинный (имея на о колоссальный практ. им теор. опыт), репу свою чесать по поводу "глюков" должен, в 1-ю очередь, именно ТЫ, и никто иной ...
и у тепя, мил мой, коль скоро ты пользуешь Делфи, под рукой всегда есть великолепный инструмент под названием Интегрированный Отладчик Делфи ... и какого шута ты им не пользуешься по сей момент - это для нас с Андреем и коллегами составляет великую гостайну ... в каковую (в тайности применения которого в поисках истины) без твоего высочайшего соизволения мы не имеем возможности "въехать"
← →
Digitman © (2004-03-19 16:36) [42]
> slgeo
слухай сюда ...
при всем моем уважении к тебе, искренне пытающегося найти "первопричину", и к Андрею, искренне пытающегося наставить тебя на путь истинный (имея на о колоссальный практ. им теор. опыт), репу свою чесать по поводу "глюков" должен, в 1-ю очередь, именно ТЫ, и никто иной ...
и у тепя, мил мой, коль скоро ты пользуешь Делфи, под рукой всегда есть великолепный инструмент под названием Интегрированный Отладчик Делфи ... и какого шута ты им не пользуешься по сей момент - это для нас с Андреем и коллегами составляет великую гостайну ... в каковую (в тайности применения которого в поисках истины) без твоего высочайшего соизволения мы не имеем возможности "въехать"
← →
Digitman © (2004-03-19 16:36) [42]
> slgeo
слухай сюда ...
при всем моем уважении к тебе, искренне пытающегося найти "первопричину", и к Андрею, искренне пытающегося наставить тебя на путь истинный (имея на о колоссальный практ. им теор. опыт), репу свою чесать по поводу "глюков" должен, в 1-ю очередь, именно ТЫ, и никто иной ...
и у тепя, мил мой, коль скоро ты пользуешь Делфи, под рукой всегда есть великолепный инструмент под названием Интегрированный Отладчик Делфи ... и какого шута ты им не пользуешься по сей момент - это для нас с Андреем и коллегами составляет великую гостайну ... в каковую (в тайности применения которого в поисках истины) без твоего высочайшего соизволения мы не имеем возможности "въехать"
← →
slgeo (2004-03-19 16:55) [43]> Digitman
А то что я выяснил что возвращает функция хочешь сказать мне винда вывалила большими буквами на синем экране?
То что чешу репу уже третий день и только после долгих и бесполезных действий обратился за помощью в форум, а кроме
споров двух, "имеющих колоссальный практ. им теор. опыт" админов я не увидел... то, о чем вы спорили, перепробовано в течение месяца согласно правилам камасутры и Билла...
Вопрос был следующим... Кратко...
Почему, при соблюдении правил программирования, как основных так и не очень, прога работает на одном железе и не работает на другом?
Это ИЗ-ЗА ЖЕЛЕЗА, Винды (имеется в виду SP) или же моих кривых рук, которые уже написали довольно боьшое кол-во софта на Делфи...
Перед тем как обвинять кого-то в некомпетентности есть смысл проверить... Вы проверяли? На Винде с первым и вторым сервис паком? нет? так я и думал...
а что вы на это скажете?:
function GetOverlappedResult; external kernel32 name "GetOverlappedResult";
← →
slgeo (2004-03-19 16:55) [43]> Digitman
А то что я выяснил что возвращает функция хочешь сказать мне винда вывалила большими буквами на синем экране?
То что чешу репу уже третий день и только после долгих и бесполезных действий обратился за помощью в форум, а кроме
споров двух, "имеющих колоссальный практ. им теор. опыт" админов я не увидел... то, о чем вы спорили, перепробовано в течение месяца согласно правилам камасутры и Билла...
Вопрос был следующим... Кратко...
Почему, при соблюдении правил программирования, как основных так и не очень, прога работает на одном железе и не работает на другом?
Это ИЗ-ЗА ЖЕЛЕЗА, Винды (имеется в виду SP) или же моих кривых рук, которые уже написали довольно боьшое кол-во софта на Делфи...
Перед тем как обвинять кого-то в некомпетентности есть смысл проверить... Вы проверяли? На Винде с первым и вторым сервис паком? нет? так я и думал...
а что вы на это скажете?:
function GetOverlappedResult; external kernel32 name "GetOverlappedResult";
← →
Digitman © (2004-03-19 17:11) [44]
> а что вы на это скажете?:
для начала я скажу, что твой исх.текст, реализующий алгоритм транспорта - большая каша ..
← →
Digitman © (2004-03-19 17:11) [44]
> а что вы на это скажете?:
для начала я скажу, что твой исх.текст, реализующий алгоритм транспорта - большая каша ..
← →
Verg © (2004-03-19 17:11) [45]
> function GetOverlappedResult; external kernel32 name "GetOverlappedResult";
А что на это должны сказать?
Функция такая из kernel32. Возвращает результат выполнения Overlapped IO.
Если ф-ция WaitFor возвращает Signaled, а кол-во принятых байт равно нулю, то это значит, что соединение было закрыто.
Все, и не только это бесчисленное число раз проверялось и не только мной (нами), но и тысячами работоспособных программ.
> Почему, при соблюдении правил программирования, как основных
> так и не очень, прога работает на одном железе и не работает
> на другом?
Я уже тебе говорил выше [17],[18], что процедура приема сделана неверно.
> SetLength(Buf, 18);
> nRead := Stream.Read(Buf[1], 18);
> // SetLength(Buf, nRead); если убрать комментарий то
> Buf очищается
> if POS("UPDATE!",Buf)=1 then
> begin
И здесь тоже неверно. Кто тебе обещал, что Read примет всю заголовочную строку за раз?
Все это, конечно, справедливо если драйвера TCP/IP не повреждены.
← →
Verg © (2004-03-19 17:11) [45]
> function GetOverlappedResult; external kernel32 name "GetOverlappedResult";
А что на это должны сказать?
Функция такая из kernel32. Возвращает результат выполнения Overlapped IO.
Если ф-ция WaitFor возвращает Signaled, а кол-во принятых байт равно нулю, то это значит, что соединение было закрыто.
Все, и не только это бесчисленное число раз проверялось и не только мной (нами), но и тысячами работоспособных программ.
> Почему, при соблюдении правил программирования, как основных
> так и не очень, прога работает на одном железе и не работает
> на другом?
Я уже тебе говорил выше [17],[18], что процедура приема сделана неверно.
> SetLength(Buf, 18);
> nRead := Stream.Read(Buf[1], 18);
> // SetLength(Buf, nRead); если убрать комментарий то
> Buf очищается
> if POS("UPDATE!",Buf)=1 then
> begin
И здесь тоже неверно. Кто тебе обещал, что Read примет всю заголовочную строку за раз?
Все это, конечно, справедливо если драйвера TCP/IP не повреждены.
← →
slgeo (2004-03-19 17:29) [46]Минутку... если повреждены драйвера, сеть будет работать?
← →
slgeo (2004-03-19 17:29) [46]Минутку... если повреждены драйвера, сеть будет работать?
← →
Verg © (2004-03-19 17:46) [47]NetBEUI?
← →
Verg © (2004-03-19 17:46) [47]NetBEUI?
← →
slgeo (2004-03-19 18:05) [48]Обычный TCP/IP. Работает аська, инет через вингейт, работает вся сеть... в этой сети на двух машинах прога работает, на трех не работает...
← →
slgeo (2004-03-19 18:05) [48]Обычный TCP/IP. Работает аська, инет через вингейт, работает вся сеть... в этой сети на двух машинах прога работает, на трех не работает...
← →
Verg © (2004-03-19 18:44) [49]Вот тут кусочек от клиента HTTP-шного.
Упростил все "до дуры" - попробуй запустить на "плохой" машинке.
IP адрес, порт и текст запроса по-месту изменишь на какой нужно.
Там два режима приема - через ReadFile и через recv. Попробуй оба.
Что скажет?program Client;
{$APPTYPE CONSOLE}
uses
Windows,
WinSock,
SysUtils,
SyncObjs;
var A : TSockAddrIn;
S : TSocket;
WSAData : TWSAData;
Ret : integer;
Buffer : array[0..255] of char;
Ostr : string;
FEvent : TEvent;
RecvSize : DWORD;
function ToOem(const S : string):string;
begin
Result := S;
CharToOemBuff(pchar(Result), pchar(Result), length(Result));
end;
procedure PrintErr(Err : DWORD);
begin
Writeln(ToOem(SysErrorMessage(Err)));
end;
function checksocket(Ret : integer):boolean;
begin
Result := Ret = SOCKET_ERROR;
if Result then
begin
PrintErr(Ret);
Readln;
end;
end;
function Receive_Mode1: integer;
begin
result := recv(S, Buffer, sizeof(buffer), 0);
end;
function Receive_Mode2: integer;
var
Overlapped: TOverlapped;
begin
FillChar(OVerlapped, SizeOf(Overlapped), 0);
Overlapped.hEvent := FEvent.Handle;
if not ReadFile(S, Buffer, sizeof(buffer), DWORD(Result),
@Overlapped) and (GetLastError <> ERROR_IO_PENDING) then
begin
Writeln;
PrintErr( GetLastError );
Result := SOCKET_ERROR;
end else
if FEvent.WaitFor(INFINITE) <> wrSignaled then
else begin
GetOverlappedResult(S, Overlapped, DWORD(Result), False);
FEvent.ResetEvent;
end;
end;
begin
Ret := WSAStartup(MAKEWORD(1,1), WSAData);
if Ret = NO_ERROR then
try
FEvent := TEvent.Create(nil, true, false, "");
S := socket(PF_INET, SOCK_STREAM, 0);
if S = INVALID_SOCKET then
begin
PrintErr(WSAGetLastError);
readln;
exit;
end;
try
FillChar(A, sizeof(A), 0);
A.sin_family := AF_INET;
A.sin_port := htons( 80 );
A.sin_addr.S_addr := inet_addr("194.67.57.51");
if checksocket(connect(S, A, sizeof(A))) then
exit;
Ostr := "GET / HTTP/1.0"#13#10#13#10;
if checksocket(send(S, Ostr[1], length(Ostr), 0)) then
exit;
RecvSize := 0;
repeat
Ret := Receive_Mode2;
if checksocket(Ret) then
exit;
if Ret = 0 then
begin
Writeln;
WriteLn("------- Disconnected bytes received---:", RecvSize);
readln;
exit;
end;
Inc(RecvSize, Ret);
SetString(Ostr, Buffer, Ret);
Write(ToOem(OStr));
until false;
finally
closesocket(S);
end;
finally
WSACleanup;
FEvent.Free;
end else
begin
PrintErr(Ret);
readln;
end;
end.
← →
Verg © (2004-03-19 18:44) [49]Вот тут кусочек от клиента HTTP-шного.
Упростил все "до дуры" - попробуй запустить на "плохой" машинке.
IP адрес, порт и текст запроса по-месту изменишь на какой нужно.
Там два режима приема - через ReadFile и через recv. Попробуй оба.
Что скажет?program Client;
{$APPTYPE CONSOLE}
uses
Windows,
WinSock,
SysUtils,
SyncObjs;
var A : TSockAddrIn;
S : TSocket;
WSAData : TWSAData;
Ret : integer;
Buffer : array[0..255] of char;
Ostr : string;
FEvent : TEvent;
RecvSize : DWORD;
function ToOem(const S : string):string;
begin
Result := S;
CharToOemBuff(pchar(Result), pchar(Result), length(Result));
end;
procedure PrintErr(Err : DWORD);
begin
Writeln(ToOem(SysErrorMessage(Err)));
end;
function checksocket(Ret : integer):boolean;
begin
Result := Ret = SOCKET_ERROR;
if Result then
begin
PrintErr(Ret);
Readln;
end;
end;
function Receive_Mode1: integer;
begin
result := recv(S, Buffer, sizeof(buffer), 0);
end;
function Receive_Mode2: integer;
var
Overlapped: TOverlapped;
begin
FillChar(OVerlapped, SizeOf(Overlapped), 0);
Overlapped.hEvent := FEvent.Handle;
if not ReadFile(S, Buffer, sizeof(buffer), DWORD(Result),
@Overlapped) and (GetLastError <> ERROR_IO_PENDING) then
begin
Writeln;
PrintErr( GetLastError );
Result := SOCKET_ERROR;
end else
if FEvent.WaitFor(INFINITE) <> wrSignaled then
else begin
GetOverlappedResult(S, Overlapped, DWORD(Result), False);
FEvent.ResetEvent;
end;
end;
begin
Ret := WSAStartup(MAKEWORD(1,1), WSAData);
if Ret = NO_ERROR then
try
FEvent := TEvent.Create(nil, true, false, "");
S := socket(PF_INET, SOCK_STREAM, 0);
if S = INVALID_SOCKET then
begin
PrintErr(WSAGetLastError);
readln;
exit;
end;
try
FillChar(A, sizeof(A), 0);
A.sin_family := AF_INET;
A.sin_port := htons( 80 );
A.sin_addr.S_addr := inet_addr("194.67.57.51");
if checksocket(connect(S, A, sizeof(A))) then
exit;
Ostr := "GET / HTTP/1.0"#13#10#13#10;
if checksocket(send(S, Ostr[1], length(Ostr), 0)) then
exit;
RecvSize := 0;
repeat
Ret := Receive_Mode2;
if checksocket(Ret) then
exit;
if Ret = 0 then
begin
Writeln;
WriteLn("------- Disconnected bytes received---:", RecvSize);
readln;
exit;
end;
Inc(RecvSize, Ret);
SetString(Ostr, Buffer, Ret);
Write(ToOem(OStr));
until false;
finally
closesocket(S);
end;
finally
WSACleanup;
FEvent.Free;
end else
begin
PrintErr(Ret);
readln;
end;
end.
← →
Digitman © (2004-03-19 18:47) [50]
> slgeo
все твои беды - от неумения грамотно построить алгоритм для конкретных условий и ПИО
вот псевдокод, который НАМНОГО упрощает и воспритие кода и его отладку :
procedure TSomeTransportThread.Execute;
begin
Transport := CreateTransport;
try
Requestparams := GetRequestParams(..);
Context := SendRequest(Transport, Requestparams);
Response := ReceiveResponse(Transport, Context);
finally
Transport := nil;
exit;
end;
← →
Digitman © (2004-03-19 18:47) [50]
> slgeo
все твои беды - от неумения грамотно построить алгоритм для конкретных условий и ПИО
вот псевдокод, который НАМНОГО упрощает и воспритие кода и его отладку :
procedure TSomeTransportThread.Execute;
begin
Transport := CreateTransport;
try
Requestparams := GetRequestParams(..);
Context := SendRequest(Transport, Requestparams);
Response := ReceiveResponse(Transport, Context);
finally
Transport := nil;
exit;
end;
← →
slgeo (2004-03-19 19:27) [51]>Verg
через recv пишет
------- Disconnected bytes received---: 51603
через ReadFile пишет
------- Disconnected bytes received---: 0
Что и требовалось доказать!
Только посоветуйте как быть,пожалуйста,с меня много-много пива :)
Переделывать все на recv?
← →
slgeo (2004-03-19 19:27) [51]>Verg
через recv пишет
------- Disconnected bytes received---: 51603
через ReadFile пишет
------- Disconnected bytes received---: 0
Что и требовалось доказать!
Только посоветуйте как быть,пожалуйста,с меня много-много пива :)
Переделывать все на recv?
← →
slgeo (2004-03-19 19:31) [52]Я даже kernel32.dll менял, где эта долбанная функция ReadFile, все равно никакой реакции, те же глюки
← →
slgeo (2004-03-19 19:31) [52]Я даже kernel32.dll менял, где эта долбанная функция ReadFile, все равно никакой реакции, те же глюки
← →
Verg © (2004-03-19 20:26) [53]Не знаю. Лучший способ - переустановить винды полностью. Со всеми сериспаками, так как оба способа (recv, ReadFile) работают нормально и абсолютно безглючно.
Не забудь, однако, про [17],[18] и прочие посты - это ОЧЕНЬ важно, и о совершенно "в десятку" замечаниях и оценках Digitman-а.
В следующий раз попробуй не "лезть в бутылку".
← →
Verg © (2004-03-19 20:26) [53]Не знаю. Лучший способ - переустановить винды полностью. Со всеми сериспаками, так как оба способа (recv, ReadFile) работают нормально и абсолютно безглючно.
Не забудь, однако, про [17],[18] и прочие посты - это ОЧЕНЬ важно, и о совершенно "в десятку" замечаниях и оценках Digitman-а.
В следующий раз попробуй не "лезть в бутылку".
← →
slgeo (2004-03-19 20:49) [54]переустановка ОС не входит в планы (клиенты злые и неотзывчивые намечаются, причем территориально достаточно удаленные), поэтому обйдемся пока recv. Еще раз будем знать, что надо поглубже с исходники забираться.
Спасибо Verg и Digitman за то что поделились опытом, теперь и у нас что-нибудь останется
Пиво куда приносить??? :)
← →
slgeo (2004-03-19 20:49) [54]переустановка ОС не входит в планы (клиенты злые и неотзывчивые намечаются, причем территориально достаточно удаленные), поэтому обйдемся пока recv. Еще раз будем знать, что надо поглубже с исходники забираться.
Спасибо Verg и Digitman за то что поделились опытом, теперь и у нас что-нибудь останется
Пиво куда приносить??? :)
← →
Verg © (2004-03-19 20:58) [55]Мылом присылай :)
А зарегистрироавтья? Кто ты и откуда, парень? Давноль живешь?
← →
Verg © (2004-03-19 20:58) [55]Мылом присылай :)
А зарегистрироавтья? Кто ты и откуда, парень? Давноль живешь?
Страницы: 1 2 вся ветка
Текущий архив: 2004.04.11;
Скачать: CL | DM;
Память: 0.83 MB
Время: 0.039 c