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

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

Неправельный приём/передача данных [D6, WinXP]


Delpher_Gray ©   (2004-04-02 14:30:00) 

Така япроблема...
В программе сложные данные посылаются в обе стороны, и иногда бывают глюки...
Использую неблокирующиеся сокеты.

Сначала посылаю перфикс, содержащий парамерты:
1. Функция (что сделать с данными): integer
2. Размер данных идущих после префикса: integer

После посылки префикса посылаются сами данные, ну а после полного приёма программа решает что делать с принятыми данными, в зависимости от функции указанной в префиксе.

Вот и сам код приёма:

...

type
 TPrefix = packed record
   FuncCode: integer;
   DataSize: integer;
 end;
 PPrefix = ^TPrefix;

...

var
 PrefixReceive: boolean; // Режим приёма (префикс/данные)
 PrefixOffset: integer; // Сколько байт префикса ещё не приняли
 DataSize: integer; // Сколько байт данных ещё не приняли
 Buf: array[0..1024] of Byte; // Буфер
 MS: TMemoryStream; // Сюда записывается содержимое буффера

...

procedure TMain.ClientSocketRead(Sender: TObject;
 Socket: TCustomWinSocket);
var
 BytesRead: integer;
begin
 if PrefixReceive = true then
 begin
   BytesRead := Socket.ReceiveBuf(Buf[PrefixOffset], SizeOf(Prefix) - PrefixOffset);
   Inc(PrefixOffset, BytesRead);
   if PrefixOffset = SizeOf(Prefix) then
   begin
     DataSize := PPrefix(@Buf)^.DataSize;
     StreamSize := DataSize;
     Prefix.FuncCode := PPrefix(@Buf)^.FuncCode;  
     Prefix.DataSize := PPrefix(@Buf)^.DataSize;

     if DataSize > 0 then
       PrefixReceive := false // Если есть данные, то переводим программу в режим приёма данных
     else
       PrefixOffset := 0; // Если данных нет, то режим приёма префикса
   end;
 end else
 begin
   Application.ProcessMessages;
   BytesRead := Socket.ReceiveBuf(Buf, Min(DataSize, SizeOf(Buf)));
   MS.Write(Buf, BytesRead);

   Dec(DataSize, BytesRead);

   if DataSize = 0 then
   begin
     // Данные приняты - выполняем операции с MS

     MS.Clear;

     // Переводим сервер обратно в режим прёма префикса
     PrefixReceive := true;
     PrefixOffset := 0;
     StreamSize := 0;
   end;
 end;
end;


А вот и код отсылки данных:

...

var
 Prefix: TPrefix;

...

MS.LoadFromFile(...);
Prefix.FuncCode := 0;
Prefix.DataSize := MS.Size;

MS.Position := 0;

ClientSocket.Socket.SendBuf(Prefix, SizeOf(TPrefix));
ClientSocket.Socket.SendBuf(MS.Memory^, MS.Size);

...


Проблема заключается в том, что если я вызову несколько раз сразу (раз 5 в секунду) функцию передачи данных, то принемающий получит повреждённые данные !

В чём же дело !?

Заранее благодарен !


Delpher_Gray   (2004-04-03 11:07:00) [1]

Люди ау ! Помогите решить пролему...


Delpher_Gray   (2004-04-02 20:49:00) [2]

Уже начал читать...
Всё равно ты подскажи на конктерном примере как исплавить глюки то !? А там с помошью статьи я уже догонюсь что и как...


Digitman   (2004-04-02 16:11:00) [3]


> Должно же поидеи


по какой такой "поидеи" ?! ты в состоянии хелп внимательно перечитать ? ты в состоянии проанализировать исх.текст компонента, благо он прямо перед носом у тебя ? ты в состоянии, прежде чем браться за отнюдь нетривиальную задачу, посетить http://book.itep.ru/7/sock_71.htmи проштудировать от корки до корки, прежде чем метаться ?


Delpher_Gray   (2004-04-02 16:01:00) [4]

Application.ProcessMessages - обязательно выкидывать!?
Просто когда получаю файл, программы подвисает :(

А событие OnWrite у меня возникает только один раз после подключения ! Должно же поидеи возникать каждый раз после посылки данных !?


Digitman   (2004-04-02 15:52:00) [5]

ты не понимаешь что ли ? тебе уже сказали - ВЫКИНЬ Application.ProcessMessages из своего текста ! и цикл выкинь !

ClientSocket.Socket.SendStream(MS);

все !!

и раньше чем получишь событие OnWrite даже и не дергайся что-либо еще посылать !


Verg   (2004-04-02 15:51:00) [6]


> Delpher_Gray ©   (02.04.04 15:43) [3]
> Переделал код так:
>  Send := ClientSocket.Socket.SendBuf(MS.Memory^, MS.Size);
>  while Send < SizeOf(MS.Size) do
>    Application.ProcessMessages;


Ты чего делаешь?! Опомнись!


Delpher_Gray   (2004-04-02 15:43:00) [7]

Переделал код так:
 Send := ClientSocket.Socket.SendBuf(MS.Memory^, MS.Size);
 while Send < SizeOf(MS.Size) do
   Application.ProcessMessages;


Но всё равно ошибки !
Люди подскажите пожалуйста как переделать код, чтоб неглючило !?


Delpher_Gray   (2004-04-02 15:43:00) [8]

Сорри, в коде оишибка ! Не SizeOf(MS.Size), а MS.Size


Digitman   (2004-04-02 15:13:00) [9]

чудовищно

у меня уже язык отсох долдонить одно и то же


Verg   (2004-04-02 14:49:00) [10]


> Application.ProcessMessages;


Выкинь эту строчку.


> ClientSocket.Socket.SendBuf(Prefix, SizeOf(TPrefix));
> ClientSocket.Socket.SendBuf(MS.Memory^, MS.Size);


Так делать нельзя.

WSAEWOULDBLOCK и все такое.
Где анализ результата ф-ций передачи данных?!


Наверх

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