Форум: "Сети";
Текущий архив: 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