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

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

TIdUDPserver


Страницы:   1 2

DesWind ©   (2006-08-17 14:30:00) 

Есть UDP-клиент, который отправляет данные таким образом

procedure SomeEvent(Sender: TObject);
var
str: string

begin

....
udpClient.Send(str);

end;

Настроен на конкретный IP.

Есть UDP сервер, настроенный(может не правильно) принимать пакеты с любого IP.


procedure TSomeThread.Execute;
var
Str: string;

begin
 Str:=dtmRecive.udpRecive.ReceiveString();
 CritSec.Acquire;
  try
   DataStrs:=DataStrs+Str;
  finally
   CritSec.Release;
  end;
end;


Так вот строки приходят через одну, т.е если посылать то "А" то "В" - приходят только "В". Что я делаю не так?


Ketmar   (2006-08-17 17:08:00) [1]

> [32] Slym ©   (17.08.06 16:56)
см. моё [29]. "да и то -- при условии, что операнды не меняются".
кажется, мы
а) загадили ветку оффтопиком
б) говорим об одном и том же, но разными словами
предлагаю с оффтопом закруглиться. %-)


DesWind   (2006-08-17 17:06:00) [2]

Фих, там.... Не-а не влияет.... буду сравнивать.


DesWind   (2006-08-17 17:01:00) [3]

Хм....

> Slym ©   (17.08.06 16:47) [30]

Знаешь в чем разница? Я использовал DataModule для размещения компонента... Создал динамически и все заработало.... Спасибо!


Slym   (2006-08-17 16:56:00) [4]

или
s:=IntToStr(Random(MaxInt));
write(s[1]);
p:=pchar(s);
sleep(0);
pbytearray(p)[1];


жесткая привязка к выделенной памяти p:=pchar(s);
другой поток изменил строку, реалокнул память и асталявиста p - невалидный указатель :(
в строках потокозащищен только подсчет ссылок (PStrRec^.RefCount)! память выделяемая под содержимое строки не защищена...


Slym   (2006-08-17 16:49:00) [5]

Ketmar ©   (17.08.06 16:39) [29]
неоткуда ему взяться.

оттуда. что пока ты sleep другой поток тебе длинну строки изменил а ты по индексу букву достаешь, а длинна меньше стала :(


Slym   (2006-08-17 16:47:00) [6]

program Project1;

{$APPTYPE CONSOLE}

uses
 SysUtils,
 Classes,
 SyncObjs,IDUDPServer;

type
 TTestThread=class(TThread)
 protected
   procedure Execute; override;
 end;
var Sock:tIDUdpServer;
var s:string;
var t:TTestThread;
var cs:TCriticalSection;
var i:integer;

procedure TTestThread.Execute;
var str:string;
begin
 FreeOnTerminate:=true;
 repeat
   str:=Sock.ReceiveString;
   cs.Enter;
   try
     s:=s+str;
   finally
     cs.Leave;
   end;
 until terminated;
end;

begin
 cs:=TCriticalSection.Create;
 try
   Sock:=tIDUdpServer.Create;
   try
     Sock.DefaultPort:=3052;
     Sock.Active:=true;
     t:=TTestThread.Create(false);
     for i:=0 to 255 do
     begin
       sleep(1000);
       cs.Enter;
       try
         Writeln(s)
       finally
         cs.Leave
       end;
     end;
     t.Terminate;
   finally
     Sock.Free;
   end;
 finally
   cs.Free;
 end;
end.


Ketmar   (2006-08-17 16:39:00) [7]

> [22] Slym ©   (17.08.06 16:05)
собственно, а кто сказал, что IntToStr() и StrToInt() -- потокобезопасные? потокобезопасные, афаир, только атомарные операции типа "+". да и то -- при условии, что операнды не меняются.
а AV быть не должно. неоткуда ему взяться.


DesWind   (2006-08-17 16:32:00) [8]

Честно!!!!! Кода больше нет!!! ))) Это просто модель.


Slym   (2006-08-17 16:30:00) [9]

ThreadedEvent влияет только на безопасность/стабильность работы
если ты в OnUDPRead при ThreadedEvent=true начнешь к форме приставать, то возможен Эксепшн, ThreadedEvent=false вызовет Synchronize тем самым защитит от многопоточного доступа к форме


DesWind   (2006-08-17 16:30:00) [10]

Ну забыл while скопировать )))

while not Terminated do
 begin
  str:=dtmRecive.udpRecive.ReceiveString;
  CritSec.Acquire;
  try
   DataStrs:=DataStrs+Str;
  finally
  CritSec.Release;
  end;
 end;

и есть еще в основном модуле

procedure TfmMain.FormCreate(Sender: TObject);
begin
RecThrd:=TReciveTread.Create(false);
tmrRecive.Enabled:=true;
end;

procedure TfmMain.FormDestroy(Sender: TObject);
begin
tmrRecive.Enabled:=false;
RecThrd.Terminate;
RecThrd.WaitFor;
RecThrd.Free;
end;

procedure TfmMain.tmrReciveTimer(Sender: TObject);
begin
CritSec.Acquire;
memData.Text:=DataStrs;
CritSec.Release;
end;


Slym   (2006-08-17 16:23:00) [11]

повторюсь:
ошибка гдето в остальном коде...
ибо твои
procedure TSomeThread.Execute;
var Str: string;
begin
Str:=dtmRecive.udpRecive.ReceiveString();
CritSec.Acquire;
 try
  DataStrs:=DataStrs+Str;
 finally
  CritSec.Release;
 end;
end;

не код потока :(


DesWind   (2006-08-17 16:19:00) [12]

Отправляю с интервалом в 1 с, попеременно символ "А" и "В". Хочу на сервере в отдельном потоке получать эти символы в той последовательности в которой оправил обрабатывать и передавать обработанные данные следующему потоку. Впринципе все это можно сделать поставив свойство ThreadedEvent в true. Тогда событие OnUDPRead будет вызываться в отдельном потоке и в этом же  событии полученую строку и обрабатывать. Но меня всежтаки беспокоит, что не получилось нормально принять данные по принципу описаному в вопросе.


Slym   (2006-08-17 16:08:00) [13]

DesWind ©   (17.08.06 16:02) [21]
Вообще что хочется тебе получить? если получаешь не то то с каким эталоном сравнивать?


Slym   (2006-08-17 16:05:00) [14]

должен быть именно AV... может у тебя i<maxint быстро сработало... оттуда WaitFor уже убитого потока


DesWind   (2006-08-17 16:02:00) [15]


> Если нарушен порядок символов так это от того что порядок
> пакетов UDP не гарантирует


А разве буфер не очищается послевыборки пакета? ведь как говорил - я гарантированно успеваю выбирать пакет до прихода следующего.


Ketmar   (2006-08-17 16:00:00) [16]

> [18] Slym ©   (17.08.06 15:54)
анализировать, что за ошибка -- лень. потому просто поверю на слово пока. %-)

зыж читал исхордник system.pas. а по-моему, она всё-таки вертится. не зря же они там InterlockedXXX() используют? глубоко анализировать лень. но есть подозрение, что задумывались именно как потокобезопасные.


Ketmar   (2006-08-17 15:59:00) [17]

> [18] Slym ©   (17.08.06 15:54)
не AV, а Thread Error: Неверный дескриптор (6). сразу. %-)


Slym   (2006-08-17 15:54:00) [18]

Через сколько секунд AV получил?


Slym   (2006-08-17 15:53:00) [19]

более наглядный пример: (поиграй {$define threadsafe})
program Project2;

{$APPTYPE CONSOLE}
//{$define threadsafe}

uses
 SysUtils,Classes,SyncObjs;

type
 TTestThread=class(TThread)
 protected
   procedure Execute; override;
 end;

var s:string;
var t:TTestThread;
{$ifdef threadsafe}
var cs:TCriticalSection;
{$endif}

procedure TTestThread.Execute;
var i:integer;
begin
 FreeOnTerminate:=true;
 repeat
   {$ifdef threadsafe}
   cs.Enter;
   try
   {$endif}
     s:=IntToStr(Random(MaxInt));
     s:=s+s+s+s+s+s+s+s+s+s+s+s;//усилим эффект
     i:=length(s);
     sleep(0);
     write(s[i]);
   {$ifdef threadsafe}
   finally
     cs.Leave;
   end;
   {$endif}
 until not(i<maxint);
end;

begin
 {$ifdef threadsafe}
 cs:=TCriticalSection.Create;
 try
 {$endif}
   TTestThread.Create(false);
   t:=TTestThread.Create(false);
   t.WaitFor;
 {$ifdef threadsafe}
 finally
   cs.Free;
 end;
 {$endif}
end.


Ketmar   (2006-08-17 15:53:00) [20]

> [13] Slym ©   (17.08.06 15:36)
убедил.


Страницы:   1 2

Наверх

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