-
FireMan_Alexey © (02.06.11 01:32) [19]
Да какие обиды? Пинок в нужном направлении самое то!
-
В принципе принятие и отправку данных можно расписать по следующему алгоритму(во всяком случае я так делал):
1. Создаешь буферы на прием и отправку!!! 2. Ждешь события OnWrite потом посылаешь данные до тех пор, пока не получишь SOCKET_ERROR или данные не закончатся!!! 3. Ждешь событие OnRead и складываешь все в буфер приема, а когда необходимое кол-во данных оказывается в буфере, то проверяешь на корректность и т.д. 4. При дисконнекте освобождаешь буферы. 5. ВСЕ!!! :)
Сейчас поищу пример, только с моим компонентом! Но там должно быть понятно и так...
-
Type
BuffType=Array of Byte;
procedure TForm1.ClientSocket1Read(Sender: TObject;
Socket: TCustomWinSocket);
Var
BuffTemp:BuffType;
Size,ReadSize:Integer;
begin
Size:=Socket.ReceiveLength;
SetLength(BuffTemp,Size);
ReadSize:=Socket.ReceiveBuf(BuffTemp,Size);
If ReadSize>0 Then BuffRead.Write(BuffTemp,ReadSize);
SetLength(BuffTemp,0);
end;
Const
MaxWrite=4096;
procedure TForm1.ClientSocket1Write(Sender: TObject;
Socket: TCustomWinSocket);
Var
BuffTemp:BuffType;
Size,WriteSize:Integer;
begin
While BuffWrite.Size>0 do
Begin
SetLength(BuffTemp,MaxWrite);
Size:=BuffWrite.Read(BuffTemp,MaxWrite);
WriteSize:=Socket.SendBuf(BuffTemp,Size);
SetLength(BuffTemp,0);
If WriteSize>0 Then
Begin
BuffWrite.Position:=0;
BuffWrite.Delete(WriteSize);
End
Else
Break;
End;
end; Напиши, если нужен исходный код моего класса по типу MemoryStream! Он на дин, массивах! :)
-
Это то что иероглифами!!!
{BuffRead - мой класс, но можно использовать и TMemoryStream, но мой удобней ;) }
-
Здравствуйте! Тоже бьюсь с сокетами, транспорт впринципе работает, но есть проблеммы. Подскажите пож-та кто знает. Проблема такая: В событиях по приему данных (ClinetRead или ServerClientRead) идет определение размера пакета данных и следом прием в цикле, пока весь пакет не будет принят. При этом находясь в режиме приема, это событие возникает несколько раз. Если процесс приема уже ведется и еще не закончен, то я выхожу из всех последующих срабатываний ClinetRead .... После приема пакета данных выхожу из события ... Проблема в том что при поступлении новых данных, событие ClinetRead или ServerClientRead в какой то произвольный момент может не сработать, несмотря на то что в сокете есть данные, оно перестает срабатывать. Если при этом принять данные в какой либо функции - событие продолжает работать.
Можно ли какой либо командой выйдя из обработчика ClinetRead заставить сработать этот обработчик снова, если в сокете есть данные?
-
На то есть три метода - ReceiveLength, ReceiveBuf и ReceiveText.
Любому из этих методов методу глубоко фиолетово откуда их вызывают - из обработчика OnXXXRead или не из обработчика, на их работоспособность это никак не влияет.
-
> Сергей М. © (11.01.12 13:41) [25]
Я использую методы ReceiveLength и ReceiveBuf. Смысл в том, что я не выхожу из обработчика OnXXXRead пока не будет принят весь известный мне оъбем данных. При этом событие OnXXXRead срабатывает неоднократно, а потом перестает срабатывать вообще. Прога при этом не висит.
Ну то есть примерно так: 1.Например сервер послал клиенту 100кб 2.на клиенте возникает событие OnXXXRead так как не все 100 кб придут клиенту сразу событие OnXXXRead срабатывает у меня несколько раз ... но я принимаю данные (все 100кб) в первом событии, пока не приму все 100кб, а из последующих срабатываний событий выхожу ... после этого покидаю первое событие OnXXXRead, в котором принимал данные .... все хорошо ... работает, принимает, данные не теряет .... Когда сервер еще что нибудь пошлет, опять событие срабатывает, принимает ... НО НЕ ВСЕГДА, в какой то момент что то втыкается ...и не смотря на то что на клиент отосланы данные, событие OnXXXRead не срабатывает.
Что то можно сделать вне обработчика OnXXXRead чтоб он опять сработал если в сокете есть данные? Или обязательно менять структуру приема данных?
-
> я принимаю данные (все 100кб) в первом событии
В режиме nonBlocking это неразумное решение.
Возникло OnRead - обрабатывай его и читай в обработчике не более чем столько сколько в этот момент кажет ReceiveLength. Остальные данные никуда не пропадут - возникнут очередные OnRead и в них ты продолжишь получение очередных принятых от партнера и доступных данных.
-
Замечено, что при срабатывании события OnXXXRead, если не принять данные и выйти из него, то последующих срабатываний события OnXXXRead возникать не будет ...
Так вот, можно ли сделать что нибудь ("переинициализировать" что ли ), чтоб при такой ситуации, оно сработало?
-
> при срабатывании события OnXXXRead, если не принять данные > и выйти из него, то последующих срабатываний события OnXXXRead > возникать не будет
Да, не будет, если из очереди поступивших от партнера данных тобой выбраны ВСЕ данные. Если же выбраны не все, то событие обязано возникнуть минимум еще однократно. И если оно у тебя не возникает, значит ты что-то накосячил в коде.
-
> Сергей М. © (11.01.12 15:09) [27]
Ясно ... да, у меня nonBlocking ....
ну тогда, мне предется переделывать схему приема и обработки данных ... типа писать все в TFileStream в OnRead, а в другом потоке производить разбор данных ... пойдет по такой схеме? только сложности на серверной стороне ... там ведь много клиеннтов может быть, разбор данных усложняется ...
-
> мне предется переделывать схему приема и обработки данных
А это уже твоя личная драма что ты сразу не пошел по верному пути.
> писать все в TFileStream в OnRead, а в другом потоке производить > разбор данных ... пойдет по такой схеме?
Такая схема еще дерьмовей. TFileStream тут как корове седло : наверняка вполне сойдет и TMemoryStream. Да и зачем другой поток, если ты даже при текущем решении без него обходишься ?
-
> Сергей М. © (11.01.12 15:26) [31]
Большое спасибо за совет и разъяснеия!
Ну как мне кажется ... в OnRead читать данные, сохранять, и быстро выходить ... А обрабатывать и геагировать на принятые данные уже в другом месте, в потоке, дабы не грузить остальную часть приложения ... а?
А FileStream вмесо MemoryStream чтоб память не занимать ... может напрасно конечно? :)
-
> в OnRead читать данные, сохранять, и быстро выходить
Именно так и правильно - на то и существует неблокирующий режим.
-
> Сергей М. © (11.01.12 16:00) [33]
ОК - Спасибо!
А как считаешь, лучше так реализовывать, как сказано выше, в неблокирующем режиме, или попробовать с блокирующим разобраться?
Работать в блокирующем режиме я не пробовал?
-
-
Хорошо! Спасибо!
|