-
не напиши завтра а напишу завтра, конечно...
-
> AlexNe (05.07.08 21:21) [14] > > Собственно проблема возникла после замены асинхронного, > но кривого TClientSocket на не кривой, но синхронный TIdTCPClient
Есть ещё ICS. Асинхронный и не очень кривой.
-
to Германн Спасибо. Буду иметь в виду на будущее.
-
AlexNe (05.07.08 21:21) [14] TClientSocket Самый прямой из простых оберток на WinSock... и не только асинхронный, но синхронный см ClientType:=ctBlocking;
-
to Slym Cвязь через TClientSocket с сервером реального времени (на машине под DOS) у меня работала устойчиво только при условии установки наивысшего приоритета для всего клиентского Win приложения. Засунуть в специальный поток его проблематично. При этом, если загрузить сильно клиента, например перерисовкой интерфейса, то часть приходящих с сервера пакетов TClientSocket просто терял... TIdTCPClient в отдельном потоке теряет ничего.
-
AlexNe (08.07.08 11:58) [24] Cвязь через TClientSocket покажи как делал AlexNe (08.07.08 11:58) [24] Засунуть в специальный поток его проблематичноничего проблемного: unit Unit2;
interface
uses
Classes,Scktcomp,winsock;
type
TSockThread = class(TThread)
private
protected
procedure Execute; override;
end;
implementation
function SockWaitForData(ASocket:TSocket; ATimeout: Longint): Boolean;
var
FDSet: TFDSet;
TimeVal: TTimeVal;
begin
TimeVal.tv_sec := ATimeout div 1000;
TimeVal.tv_usec := (ATimeout mod 1000) * 1000;
FD_ZERO(FDSet);
FD_SET(ASocket, FDSet);
Result := select(0, @FDSet, nil, nil, @TimeVal) > 0;
end;
function SockReadLn(ASocket:TSocket;ATerminator:char;AMaxLineLength:integer;ATimeOut:Long int):string;
var
Buf:array[byte] of char;
SizeBuf:integer;
r,i:integer;
s:string;
begin
SizeBuf:=SizeOf(Buf);
result:='';
while SockWaitForData(ASocket,ATimeOut) do
begin
r:=recv(ASocket, Buf, SizeBuf, MSG_PEEK);
if r=SOCKET_ERROR then RaiseSocketError(WSAGetLastError, 'recv');
i:=LCharPos(@Buf,ATerminator,r);
if i<>0 then r:=i;
r:=recv(ASocket, Buf, r, 0);
if r=SOCKET_ERROR then RaiseSocketError(WSAGetLastError, 'recv');
SetString(s,Buf,r);
result:=result+s;
if i<>0 then Break;
end;
if length(result)=0 then exit;
i:=length(result)-1;
if (ATerminator=LF) and (result[i]=CR) then Dec(i);
SetLength(result,i);
end;
procedure TSockThread.Execute;
var
Socket:TClientWinSocket;
s:string;
Code:integer;
begin
Socket:=TClientWinSocket.Create(-1);
try
Socket.ClientType:=ctBlocking;
Socket.Open('192.168.14.2','','',3128);
Socket.SendText('CONNECT hostname HTTP/1.0'#13#10);
Socket.SendText(#13#10);
s:=SockReadLn(Socket.SocketHandle);
Fetch(s,' ');
Code:=StrToIntDef(Fetch(s,' '),200);
if Code<>200 then raise Exception.CreateFmt('Bad HTTP status code: %d %s',[Code,s]);
repeat until
SockReadLn(PeerSocket.SocketHandle) = '';
...
finally
Socket.Free;
end;
end;
end.
-
Что-то мне кажется, что решение задачи слишком усложнено. Какую проблему решает система?
-
Дмитрий Белькевич © (08.07.08 12:25) [26] Какую проблему решает система? 2. что за DOS сервер, не порали найти/сделать win аналог?
-
> [0] AlexNe (05.07.08 18:41)
> причем поток сокета TIdTCPClient имеет наивысший приоритет.
сетевым потоком не нужно ставить наивысший приоритет, пустая трата процессорного времени.. работа с сетью - довольно медленная операция. проблема не в инди скорее всего, там tcp клиент/сервер довольно грамотно написаны. Если приложение падает и даже исключение не вылетает, то скорее всего где-то неверная работа с памятью, либо что-то не корректно вызывается и система сразу прихлопывает приложение. Сетевая часть думаю особо не при чем.
-
Извиняюсь за задержку - у меня последний день командировки и рвут на части. to Slym © Возможно, что-то было с TClientSocket в потоке сделано не так, нужно рыть старый исходник. Но сокет с DOS машиной через несколько минут 10Гц обмена вис, причем ситуация решалась только перезагрузкой DOS
to Дмитрий Белькевич © Нет, не усложнено. Система решает задачу управления научным оборудованием, которое разбросано в радиусе 50 м и имеет ограничения по длине проводов связи - отсюда наличие множества серверов на разлинух компах.
to Slym © >2. что за DOS сервер, не порали найти/сделать win аналог? Найти нельзя. Сделать - во- первых нужна система жесткого реального времени, тут скорее QNX. Но главное, то кол-во самодельных железок, для которых по мере развития системы писались дрова - все переписть в обночасье никак не получится, а останавливать ради этого систему никто не даст. Так что живем как живем.
to Eraser © ? - если кто-то приостановит обмен с DOS машиной на 0.5 с., сработает защита, которая останавливает плавное движение конструкции весом 3.5т. > Если приложение падает и даже исключение не вылетает, то скорее всего > где-то неверная работа с памятью что-то похожее на конфликт реентерабельности наблюдается по логам, - два раза произошел вылет при входе в Timer.OnTimer (там ничего нет, кроме обновления интерфейсных элементов). Поставил на тестирование - до вечера, последний шанс отловить барабашку.
-
> синхронный TIdTCPClient для работы с сервером под DOS
Клиенту глубоко фиолетово, под какой ОС работает сервер. Равно как и наоборот. И синхронность или асинхронность тут совершенно ни причем.
-
>Сетевая часть думаю особо не при чем.
-
to Eraser © Предположение появилось из-за чрезвычайной редкости события - 1-2 раза за сутки, при том что старая версия с теми же серверам, оборудованием и в том же режиме не падает (хотя и теряет иногда важную информацию)
-
> AlexNe (08.07.08 19:18) [31]
Смотря что ты подразумеваешь под "сетевой частью".
Подозреваю, что ты не имеешь ни малейшего представления о модели OSI.
-
Случилось! Дебаггер указал на ошибку в потоке, в котором сидит IdTCPClient. Лог застопорился перед чтением свойства объекта-наследника соотв. потока. Т.е. какая-то аномалия при работе сокета DOS-Windows. К сожалению проверить и уточнить получится нескоро, командировка кончилась. Поскольку моя работа с системой прерывается, тему считаю временно закрытой. Всем спасибо за потраченное время и ценную информацию.
-
>Т.е. какая-то аномалия при работе сокета DOS-Windows.
Наиболее вероятная аномалия - доступ к обломкам разрушенного объекта. Объектам после разрушения присваивай nil, может ошибку удастся 'проявить'. По AV доступа к 00000000.
Еще немного информации. Если нужен хороший реалтайм, разумно выбросить весь дос и вообще все лишние писюки и, по возможности, самодельные железки вместе с дровами. Сделать промежуточный приём на однокристалках, постараться все данные собирать только ими, благо сейчас их разных есть, можно и абсолютный аналог, и дифференциальный, и цифру забирать, и по многим каналам сразу. Объединить их в сеть (есть железки с готовым железячным tcp стёком), и сливать информацию по мере доступности на писюк.
Сделать единый движок для 'пропихивания' инфы в компьютер. И несколько разных драйверов для разных входных данных.
Я, конечно, всех особенностей не знаю, но, скорее всего, должно работать без проблем.
-
> Дмитрий Белькевич © (08.07.08 22:37) [35] > разумно выбросить весь дос и вообще все лишние писюки
Легко говорить. А кто заплатит за такую переделку? Как говортся - хорошо быть здоровым и богатым.;)
-
> Дмитрий Белькевич (08.07.2008 22:37:35) [35]
Не надо nil, лучше $80808080
-
>Легко говорить. А кто заплатит за такую переделку? >Как говортся - хорошо быть здоровым и богатым.;)
Лишние писюки - продать, купить однокристалок. Разницу (если останется) - пропить ;) Вообще, всё равно придётся им что-то менять, просто 'закопаются' со временем. Хотя, может быть я и не прав. Все обстоятельства мне неизвестны.
>Не надо nil, лучше $80808080
Почему, кстати? Нашел только, что FastMM в FullDebugMode атоматом забивает память разрушенных объектов и строк этим значением.
Вот, кстати, еще одна идея: поставить FastMM в FullDebugMode.
-
> Дмитрий Белькевич (09.07.2008 12:24:38) [38]
Для того что бы отличить не инициализированое, от уничтоженого. Методика из FastMM
|