Форум: "Сети";
Текущий архив: 2002.01.14;
Скачать: [xml.tar.bz2];
ВнизС мольбой о помощи взываю!!! Найти похожие ветки
← →
Polevi (2001-10-17 11:45) [0]Файл пытаюсь переслать :-)))
Все статьи прочитал, в форумах смотрел - у людей все работает, у у меня нет :((
Отсылаю
procedure TForm1.csConnect(Sender: TObject; Socket: TCustomWinSocket);
var
FS:TFileStream;
begin
FS:=TFileStream.Create("sour.ext",fmOpenRead);
cs.Socket.SendStream(FS);
FS.Free;
end;
Принимаю
procedure TClientThread.ClientExecute;
var
FS:TFileStream;
WSS:TWinSocketStream;
RL:integer;
begin
FS:=TFileStream.Create("dest.ext",fmCreate or fmOpenWrite);
WSS:=TWinSocketStream.Create(ClientSocket,20000);
try
while (not Terminated) and ClientSocket.Connected do
if WSS.WaitForData(20000) then
begin
RL:=ClientSocket.ReceiveLength;
if FS.CopyFrom(WSS, RL)=0 then break;
end;
finally
begin
ClientSocket.Close;
WSS.Free;
FS.Free;
end;
end;
end;
На маленьких файлах все работает..
Но если размер больше 4096 -
На строке CopyFrom - Stream read error
Я понимаю что тема заезжена - но не вижу я ошибки в коде!!
Помогите, плиз..
← →
Digitman (2001-10-17 12:52) [1]procedure TClientThread.ClientExecute;
var
FS:TFileStream;
RL:integer;
SocketEvent: THandle;
buf: Pointer;
Msg: TMsg;
begin
try
FS:=TFileStream.Create("dest.ext",fmCreate or fmOpenWrite);
SocketEvent := WSACreateEvent;
WSAEventSelect(ClientSocket.SocketHandle, SocketEvent, FD_READ or FD_CLOSE);
try
while (not Terminated) and ClientSocket.Connected do
case MsgWaitForMultipleObjects(1, SocketEvent, False, INFINITE, QS_POSTMESSAGE) of
WAIT_OBJECT_0:
begin
RL:=ClientSocket.ReceiveLength;
if RL > 0 then begin
GetMem(buf, RL);
try
RL := ClientSocket.ReceiveBuf(buf^, RL);
FS.Write(buf^, RL)
finally
FreeMem(buf);
end;
end
end;
WAIT_OBJECT_0 + 1:
begin
while PeekMessage(Msg, 0, 0, 0, PM_REMOVE) do
DispatchMessage(Msg);
end;
WAIT_ABANDONED: break;
end;
finally
CloseHandle(SocketEvent);
ClientSocket.Close;
FS.Free;
end;
except
// обработка ошибок
end;
end;
← →
Evegeniy_S (2001-10-17 12:53) [2]а clienttype у тебя на сокете blocking?
← →
Polevi (2001-10-17 13:16) [3]2Evegeniy_S
blocking
2Digitman
SocketEvent := WSACreateEvent; - здесь AV выскакивает :(
И если не трудно - можно небольшие комментарии?
Я не вижу здесь тайм-аута, например..
← →
Digitman (2001-10-17 13:51) [4]что-то я глубоко сомневаюсь, что именно на SocketEvent := WSACreateEvent AV возбудится ...
Да, вот еще, в конце - не CloseHandle(SocketEvent), а WSACloseEvent(SocketEvent)
насчет тайм-аута - вместо INFINITE поставь время в мс и добавь в блок case..of вариант WAIT_TAIMAUT, в котором принимай решение, ждать дальше или закругляться
← →
Polevi (2001-10-17 14:25) [5]Хм..
WSACreateEvent лежит в sconnect..
Вот эту ф-ию надо вызвать видимо???
function LoadWinSock2: Boolean;
const
DLLName = "ws2_32.dll";
begin
Result := hWinSock2 > HINSTANCE_ERROR;
if Result then Exit;
hWinSock2 := LoadLibrary(PChar(DLLName));
Result := hWinSock2 > HINSTANCE_ERROR;
if Result then
begin
WSACreateEvent := GetProcAddress(hWinSock2, "WSACreateEvent");
WSAResetEvent := GetProcAddress(hWinSock2, "WSAResetEvent");
WSACloseEvent := GetProcAddress(hWinSock2, "WSACloseEvent");
WSAEventSelect := GetProcAddress(hWinSock2, "WSAEventSelect");
end;
end;
Вызываю - AV пропадает, ессно..
Но возникает какаято жуткая тормозня и в итоге неичего не копируется..
?
← →
Digitman (2001-10-17 14:40) [6]какая еще тормозня ? ты код трассировать умеешь ? оттассируй пошагово ClientExecute() - только тогда будешь иметь представление, что делается в каждой строчке. И вопрос сам по себе отпадет.
← →
Polevi (2001-10-17 15:23) [7]Оттрассировал..
Почему "тормозит" понял
if RL > 0 then begin
GetMem(buf, RL);
try
RL := ClientSocket.ReceiveBuf(buf^, RL);
FS.Write(buf^, RL)
finally
FreeMem(buf);
end;
Так вот если RL<=0 то цикл зависает, и ни по какому тайм-ауту не выходит..
Если поставить else break; - то первые 4k копируются и все... (else break срабатывает, видимо)
"Видимо" потому что в пошаговом режиме все вроде копируется, а если точки останова убрать - начинается см. выще.
Щас полезу в исходники разбираться..
Халява не прошла :-)))
← →
Polevi (2001-10-17 16:13) [8]Мдаа..
Переделал первоначальный вариант - отказался от CopyFrom, сделал все ручками - и все заработало на славу :-))
Вот ведь как бывает..
← →
Digitman (2001-10-17 16:37) [9]Ты пойми, что сервер ничего не знает о полном размере данных, который клиент хочет передать. Для этого клиент перед посылкой собственно данных должен послать некий префикс, значение которого позволит серверу определиться, какой длины данные суммарно будут переданы. И в цикл нужно добавить условие (переменная-счетчик, работающий на вычитание размера очер.порции принятых данных, начальное значение которой формируется из считанного префикса), проверяющее, все ли данные считаны. Протокол-то - поточный ! Цикл надо прервать, когда Счетчик = 0, тогда и файл закроется и обработка завершится.
Приведенный код - лишь скелет, показывающий, как работать с поточным гнездом. Доработай его сам (и - осознанно, а не методом тыка !) с учетом этих замечаний - и убедишься в преимуществе над использованием TWinSocketStream
← →
Polevi (2001-10-17 18:39) [10]Да, я все осознал, спасибо :-)
Я просто почемуто думал, что если ReceiveLength=0 то значит все уже скопировано..
Но все равно непонятно, почему по таймауту не выходил я из цикла..
Вместо INFINITE ставил занчение в милисек и на TIMEOUT не выходил..
Ну впрочем это видимо руки у меня кривые :-)
← →
Digitman (2001-10-18 08:52) [11]>Polevi
Я еще вот чего важное забыл (спешил, извини уж, но - мог бы и сам догадаться, почитав хэлп на сабж)
Всякий раз в блоке WAIT_OBJECT_0 перевым делом нужно сбросить сигнал объекта синхронизации SocketEvent в нач.сотояние вызовом WSAResetEvent(SocketEvent), иначе он останется в сигналящем состоянии и ты больше не дождешься его срабатывания по событиям в гнезде.
Можно обойтись и без WSAResetEvent(), но тогда нужно использовать вызов WSAEnumNetworkEvents(), автоматически сбрасывающий сигн.объект. Это чуть сложнее, но зато дает большую гибкость в обработке гнездовых событий (в т.ч. немедленное получение инфы об ошибках, связанных с тем или иным событием без необходимости их обнаружения иными методами/вызовами)
← →
Polevi (2001-10-18 10:07) [12]Спасибо, буду разбираться.
Страницы: 1 вся ветка
Форум: "Сети";
Текущий архив: 2002.01.14;
Скачать: [xml.tar.bz2];
Память: 0.47 MB
Время: 0.005 c