Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Сети";
Текущий архив: 2007.01.14;
Скачать: [xml.tar.bz2];

Вниз

TIdUDPserver   Найти похожие ветки 

 
DesWind ©   (2006-08-17 14:30) [0]

Есть 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 14:37) [1]

а зачем критическая секция? для строк не надо. %-)


 
DesWind ©   (2006-08-17 14:45) [2]

Ниче здоровее будет.


 
Ketmar ©   (2006-08-17 14:54) [3]

а вообще -- для udp нет буфера. если ты не успел забрать пакет до прихода нового -- то уже и не заберёшь никогда. есть подозрение, что пакеты приходят шутсро, а забираются медленно. потому и теряются -- старый пакет перезаписывается новым до выборки.


 
Slym ©   (2006-08-17 14:57) [4]

DesWind ©   (17.08.06 14:30)
если посылать то "А" то "В" - приходят только "В".

Файрвол на букву "А" :)


 
DesWind ©   (2006-08-17 15:01) [5]

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


 
DesWind ©   (2006-08-17 15:18) [6]

А вообще получаются очень интересные строчики на выходе типа такого "ABBBBBBBABBBBBBABBBBBBABBBBBBABBBBBBABBBBBBABBBBBBABBBBBBA", или еще какойнить рисунок.... Ниче не понимаю!!!!


 
Slym ©   (2006-08-17 15:22) [7]

Ketmar ©   (17.08.06 14:37) [1]
а зачем критическая секция? для строк не надо

Надо... строка это сложный поточно незащищенный ресурс
DesWind ©   (17.08.06 15:01) [5]
Выбирать я их точно успеваю

ошибка гдето в остальном коде...


 
Ketmar ©   (2006-08-17 15:23) [8]

так может пакеты вообще теряются нафиг в дороге. "была зима, на небе были тучи..." (ц)
по твоему коду нифига не ясно.


 
Slym ©   (2006-08-17 15:23) [9]

DesWind ©   (17.08.06 15:18) [6]
Если нарушен порядок символов так это от того что порядок пакетов UDP не гарантирует


 
Ketmar ©   (2006-08-17 15:24) [10]

> [7] Slym ©   (17.08.06 15:22)
> строка это сложный поточно незащищенный ресурс
точно? я полез читать исходник. потому как мне память подсказывает, что это не совсем правда.


 
Slym ©   (2006-08-17 15:26) [11]

Ketmar ©   (17.08.06 14:54) [3]
для udp нет буфера

откуда это? по дефолту буфер есть у всех... в т.ч. и у RAW соков только буфер то маленький... и все что в него не влазит - игнорится (UDP)


 
Ketmar ©   (2006-08-17 15:27) [12]

> [11] Slym ©   (17.08.06 15:26)
я имел в виду "такого, как для TCP, где накапливаются пакеты". накопления не происходит, новоприбывший пакет замещает старый.


 
Slym ©   (2006-08-17 15:36) [13]

Ketmar ©   (17.08.06 15:24) [10]
что это не совсем правда

попробуй:
program Project2;

{$APPTYPE CONSOLE}

uses
 SysUtils,Classes;

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

var s:string;
var t:TTestThread;

procedure TTestThread.Execute;
var i:integer;
begin
 FreeOnTerminate:=true;
 repeat
   i:=StrToInt(s);
   sleep(0);
   if i<>StrToInt(s) then raise exception.Create("Alarm");
   s:=IntToStr(i+1);
   writeln(s);
 until not(i<maxint);
end;

begin
 s:="0";
 TTestThread.Create(false);
 t:=TTestThread.Create(false);
 t.WaitFor;
end.


 
DesWind ©   (2006-08-17 15:37) [14]


> ошибка гдето в остальном коде...

Остального кода нет :), разве что по таймеру в мемо выводится DataStrs. Если перевести TidUDPServer на события (т.е. выбирать данные по событию IdUDPServer1UDPRead), то все приходит нормально как и должно, но меня события не устраивают.


 
Slym ©   (2006-08-17 15:39) [15]

Slym ©   (17.08.06 15:36) [13]
а теперь так:
program Project2;

{$APPTYPE CONSOLE}

uses
 SysUtils,Classes,SyncObjs;

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

var s:string;
var cs:TCriticalSection;
var t:TTestThread;

procedure TTestThread.Execute;
var i:integer;
begin
 FreeOnTerminate:=true;
 repeat
   cs.Enter;
   try
     i:=StrToInt(s);
     sleep(0);
     if i<>StrToInt(s) then raise exception.Create("Alarm");
     s:=IntToStr(i+1);
     writeln(s);
   finally
     cs.Leave;
   end;
 until not(i<maxint);
end;

begin
 s:="0";
 cs:=TCriticalSection.Create;
 try
   TTestThread.Create(false);
   t:=TTestThread.Create(false);
   t.WaitFor;
 finally
   cs.Free;
 end;
end.


 
Ketmar ©   (2006-08-17 15:53) [16]

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


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

более наглядный пример: (поиграй {$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.


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

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


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

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


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

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

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


 
DesWind ©   (2006-08-17 16:02) [21]


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


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


 
Slym ©   (2006-08-17 16:05) [22]

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


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

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


 
DesWind ©   (2006-08-17 16:19) [24]

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


 
Slym ©   (2006-08-17 16:23) [25]

повторюсь:
ошибка гдето в остальном коде...
ибо твои
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:30) [26]

Ну забыл 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:30) [27]

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


 
DesWind ©   (2006-08-17 16:32) [28]

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


 
Ketmar ©   (2006-08-17 16:39) [29]

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


 
Slym ©   (2006-08-17 16:47) [30]

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.


 
Slym ©   (2006-08-17 16:49) [31]

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

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


 
Slym ©   (2006-08-17 16:56) [32]

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


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


 
DesWind ©   (2006-08-17 17:01) [33]

Хм....

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

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


 
DesWind ©   (2006-08-17 17:06) [34]

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


 
Ketmar ©   (2006-08-17 17:08) [35]

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



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

Форум: "Сети";
Текущий архив: 2007.01.14;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.54 MB
Время: 0.014 c
8-1147990002
Дмитрий12
2006-05-19 02:06
2007.01.14
координаты


2-1166686128
Sergey__
2006-12-21 10:28
2007.01.14
Различное поведение НД при вставке и редактировании.


15-1166602615
mezozoy
2006-12-20 11:16
2007.01.14
Русский help по EhLib


15-1166662585
Oreolek
2006-12-21 03:56
2007.01.14
Ассемблер


1-1164380543
BBCHa
2006-11-24 18:02
2007.01.14
Установка форматов в Excele





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский