Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.05.23;
Скачать: CL | DM;

Вниз

Неправельный приём/передача данных   Найти похожие ветки 

 
Delpher_Gray ©   (2004-04-02 14:30) [0]

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

Сначала посылаю перфикс, содержащий парамерты:
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 в секунду) функцию передачи данных, то принемающий получит повреждённые данные !

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

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


 
Verg ©   (2004-04-02 14:49) [1]


> Application.ProcessMessages;


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


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


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

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


 
Digitman ©   (2004-04-02 15:13) [2]

чудовищно

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


 
Delpher_Gray ©   (2004-04-02 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) [4]

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


 
Verg ©   (2004-04-02 15:51) [5]


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


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


 
Digitman ©   (2004-04-02 15:52) [6]

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

ClientSocket.Socket.SendStream(MS);

все !!

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


 
Delpher_Gray ©   (2004-04-02 16:01) [7]

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

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


 
Digitman ©   (2004-04-02 16:11) [8]


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


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


 
Delpher_Gray ©   (2004-04-02 20:49) [9]

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


 
Delpher_Gray ©   (2004-04-03 11:07) [10]

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



Страницы: 1 вся ветка

Текущий архив: 2004.05.23;
Скачать: CL | DM;

Наверх




Память: 0.49 MB
Время: 0.068 c
14-1083679000
yevgeniy
2004-05-04 17:56
2004.05.23
Прямо неудобно спрашивать... но: как устанавливать компоненты?


3-1083132416
Mishel
2004-04-28 10:06
2004.05.23
триггер Interbase -> триггер MSSQL 2000


3-1083063540
GIL
2004-04-27 14:59
2004.05.23
Сервер в IBDataBase


1-1084261027
goliath
2004-05-11 11:37
2004.05.23
Проблема с Borland Kylix 3.0


4-1080457228
Navi
2004-03-28 11:00
2004.05.23
Извлечь иконку по расширению