Автор: sammozg
Дата сообщения: 24.02.2012 12:14
Frodo_Torbins
Благодарю за советы, но они мне не помогли, я поменял компонент на idTCPClient, вроде стало работать получше, но ни TCPClient, ни idTCPClient не работают когда я запускаю сразу 2 потока(разумеется с разными IP/Port), работает только один, пробывал создавать кучу клиентов, Запускать в разных потоках(всмысле с другим именем, и вообще писал отдельный поток), в общем устал как собака..., а он не работает (первый подвисает на соединении при запуске второго потока, второй благополучно работает, при запуске третьего, виснут первый и второй, работает тока третий и тд...). [more= Вот к чему я пришёл....]unit KRRead;
interface
uses
Classes, SysUtils, Sockets, ExtCtrls, Windows, Messages, Variants, Graphics, Controls, Forms,
Dialogs, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient;
type
Work = class(TThread)
private
{ Private declarations }
protected
procedure Execute; override;
end;
Type
Buf = array [0..511] of byte;
PBuf = ^Buf;
function crc8 (Start, UsDataLen: integer; Mes: array of byte): byte;
var
Client1: TIDTCPClient;
InputARMData: buf;
KRData: buf;
KRDataQueryByf: Buf;
buffer: buf;
KRReadWrite, Rezerv: Boolean;
implementation
uses SKRSeting, SKR, ARMIO, SKRServer, SKRWork, data;
{ Important: Methods and properties of objects in visual components can only be
used in a method called using Synchronize, for example,
Synchronize(UpdateCaption);
and UpdateCaption could look like,
procedure Work.UpdateCaption;
begin
Form1.Caption := 'Updated in a thread';
end; }
{ Work }
procedure Work.Execute;
var
KolParNastr14DOst, KolParNastr14AOst, KolParNastr14A, KolParNastrA, k, j: integer;
KR, Param, i, ii, LenSav, LenRec, KolParNastrD, KolParNastr14D: Integer;
A: Byte;
ELOKR, L, M, N, P, KolOKR4, KolOKR4Ost, TimeOut: Integer;
S, Oshibka: boolean;
begin
Oshibka:=False;
KR:=1;//SKR.KRNum;
data.Potok.KRWork[KR]:=true;
KRReadWrite:=True;
Client1:=TIDTcpClient.Create(Nil);
If data.Potok.KRRezerv[KR] then begin
Client1.Host:=SKRSeting.KRSet.KR[KR].RezIP;
Client1.Port:=StrToInt(SKRSeting.KRSet.KR[KR].RezPort);
Client1.ReadTimeout:=StrToInt(SKRSeting.KRSet.KR[KR].RezTimeOut);
end else begin
Client1.Host:=SKRSeting.KRSet.KR[KR].IP;
Client1.Port:=StrToInt(SKRSeting.KRSet.KR[KR].Port);
Client1.ReadTimeout:=StrToInt(SKRSeting.KRSet.KR[KR].TimeOut);
end;
try
Client1.Connect;
except
KRReadWrite:=false;
exit;
end;
While KRReadWrite do
begin
KRDataQueryByf[$00]:=KR;
KRDataQueryByf[$01]:=$00;
KRDataQueryByf[$04]:=$40;
KRDataQueryByf[$05]:=$01;
KRDataQueryByf[$06]:=$00; // Чтение ИНР
for Param:=0 to strtoint(SKRseting.KRSet.KR[KR].INRKol)-1 do begin //поочерёдно читаем все ИНР
KRDataQueryByf[$07]:=Param;
KRDataQueryByf[$02]:=$03; //Количество байт
KRDataQueryByf[$03]:=$00; //отправляемых
KRDataQueryByf[$08]:=crc8(0,8,KRDataQueryByf); //Считаем CRC
LenSav:=8+4*strtoint(SKRseting.KRSet.KR[KR].INR[Param+1]); //Считаем сколько должно придти
LenRec:=LenSav;
i:=0; //Сохраняем резервную копию(чтоб второй раз не считать)
Client1.WriteBuffer(KRDataQueryByf[$00], 9);
try
Client1.ReadBuffer(buffer[i],lenSav);
except
Oshibka:=True;
end;
i:=CRC8 (0,LenRec-1,buffer); //Считаем CRC
If buffer[LenRec-1]=i then //Проверяем CRC
begin
If (buffer[4] and $02)=1 then Rezerv:=true;
for i:=0 to 4*strtoint(SKRSeting.KRSet.KR[KR].INR[Param+1]) do
Begin
A:=Buffer[i+7];
Data.KRData[KR].INR[Param].INRIO[i]:=A;
end;
end;
end;//Закончили читать ИНР
// Чтение Параметров настройки
//********************
KolParNastrA:=strtoint(SKRseting.KRSet.KR[KR].AIKol);
k:=0;
If KolParNastrA>0 then //Читаем AI
begin
KolParNastr14A:=KolParNastrA div 14;
KolParNastr14AOst:=KolParNastrA mod 14;
KRDataQueryByf[$06]:=$01;
for Param:=1 to KolParNastr14A do begin //поочерёдно читаем параметры пакетами по 14 штук
KRDataQueryByf[$07]:=$0E;
KRDataQueryByf[$02]:=$2D; //Количество байт
KRDataQueryByf[$03]:=$00; //отправляемых
for j:=1 to 14 do
begin
KRDataQueryByf[j*3+5]:=(strtoint(SKRseting.KRSet.KR[KR].AI[14*k+j,1]) and $FF); //начало номера алгоблока
KRDataQueryByf[j*3+6]:=(strtoint(SKRseting.KRSet.KR[KR].AI[14*k+j,1]) shr 8); //конец номера алгоблока
KRDataQueryByf[j*3+7]:=strtoint(SKRseting.KRSet.KR[KR].AI[14*k+j,2]); //номер входа алгоблока
end;
KRDataQueryByf[$32]:=crc8(0,49,KRDataQueryByf); //Считаем CRC
LenSav:=$79; //Считаем сколько должно придти
LenRec:=LenSav;
i:=0; //Сохраняем резервную копию(чтоб второй раз не считать)
Client1.WriteBuffer(KRDataQueryByf[$00], $33);
try
Client1.ReadBuffer(buffer[i],lenSav);
except
Oshibka:=True;
end;
i:=CRC8 (0,$78,buffer); //Считаем CRC
If buffer[$78]=i then //Проверяем CRC
begin
If (buffer[4] and $02)=1 then Rezerv:=true;
for i:=0 to 111 do
Begin
A:=Buffer[i+8];
Data.KRData[KR].AI[i+k*112]:=A;
end;
end;
end;
end; //Закончили читать ПАкеты AI
//*****************
If KolParNastr14Aost>0 then
begin //''4''
KRDataQueryByf[$07]:=KolParNastr14Aost;
KRDataQueryByf[$02]:=KolParNastr14Aost*3+3; //Количество байт
KRDataQueryByf[$03]:=$00; //отправляемых
KRDataQueryByf[$06]:=$01;
for j:=1 to KolParNastr14Aost do
begin
KRDataQueryByf[j*3+5]:=(strtoint(SKRseting.KRSet.KR[KR].AI[14*k+j,1]) and $FF); //начало номера алгоблока
KRDataQueryByf[j*3+6]:=(strtoint(SKRseting.KRSet.KR[KR].AI[14*k+j,1]) shr 8); //конец номера алгоблока
KRDataQueryByf[j*3+7]:=strtoint(SKRseting.KRSet.KR[KR].AI[14*k+j,2]); //номер входа алгоблока
end;
KRDataQueryByf[KolParNastr14Aost*3+8]:=crc8(0,KolParNastr14Aost*3+8,KRDataQueryByf); //Считаем CRC
LenSav:=KolParNastr14Aost*8+9; //Считаем сколько должно придти
LenRec:=LenSav;
i:=0; //Сохраняем резервную копию(чтоб второй раз не считать)
Client1.WriteBuffer(KRDataQueryByf[$00], 9);
try
Client1.ReadBuffer(buffer[i],lenSav);
except
Oshibka:=True;
end;
i:=CRC8 (0,LenRec-1,buffer); //Считаем CRC
If buffer[LenRec-1]=i then //Проверяем CRC
begin
for i:=0 to KolParNastr14Aost*8 do
Begin
If (buffer[4] and $02)=1 then Rezerv:=true;
A:=Buffer[i+8];
Data.KRData[KR].AI[i+k*112]:=A;
end;
end ;
end; //Закончили читать остатки AI
If StrToInt(SKRSeting.KRSet.KR[KR].OKRKol)>0 then
begin
L:=1;
M:=0;
KolOKR4:=StrToInt(SKRSeting.KRSet.KR[KR].OKRKol) div 4;
KolOKR4Ost:=StrToInt(SKRSeting.KRSet.KR[KR].OKRKol) mod 4;
For ELOKR:=1 to KolOKR4 do
begin
KRDataQueryByf[$02]:=$07; //Количество байт
KRDataQueryByf[$03]:=$00; //отправляемых
KRDataQueryByf[$05]:=$01;
KRDataQueryByf[$06]:=$02;
KRDataQueryByf[$07]:=$04;
KRDataQueryByf[$08]:=L;
KRDataQueryByf[$09]:=L+1;
KRDataQueryByf[$0A]:=L+2;
KRDataQueryByf[$0B]:=L+3;
L:=L+4;
KRDataQueryByf[$0C]:=crc8(0,$0C,KRDataQueryByf);
LenSav:=$65; //Считаем сколько должно придти
LenRec:=LenSav; //Сохраняем резервную копию(чтоб второй раз не считать)
i:=0;
Client1.WriteBuffer(KRDataQueryByf[$00], $0D);
try
Client1.ReadBuffer(buffer[i],lenSav);
except
Oshibka:=True;
end;
i:=CRC8 (0,LenRec-1,buffer); //Считаем CRC
If buffer[LenRec-1]=i then //Проверяем CRC
begin
If (buffer[4] and $02)=1 then Rezerv:=true;
for i:=0 to 23*4-1 do
Begin
A:=Buffer[i+8];
Data.KRData[KR].OKR[i+M*$5c]:=A;
end;
M:=M+1;
end;
End;
If KolOKR4Ost>0 then
begin
KRDataQueryByf[$02]:=KolOKR4Ost+3; //Количество байт
KRDataQueryByf[$03]:=$00; //отправляемых
KRDataQueryByf[$05]:=$01;
KRDataQueryByf[$06]:=$02;
KRDataQueryByf[$07]:=KolOKR4Ost;
For i:=0 to KolOKR4Ost do
begin
KRDataQueryByf[i+8]:=L+i;
end;
KRDataQueryByf[KolOKR4Ost+8]:=crc8(0,KolOKR4Ost+8,KRDataQueryByf);
LenSav:=23*KolOKR4Ost+9; //Считаем сколько должно придти
LenRec:=LenSav; //Сохраняем резервную копию(чтоб второй раз не считать)
i:=0;
Client1.WriteBuffer(KRDataQueryByf[$00], KolOKR4Ost+9);
try
Client1.ReadBuffer(buffer[i],lenSav);
except
Oshibka:=True;
end;
i:=CRC8 (0,LenRec-1,buffer); //Считаем CRC
If buffer[LenRec-1]=i then //Проверяем CRC
begin
If (buffer[4] and $02)=1 then Rezerv:=true;
for i:=0 to 23*KolOKR4Ost-1 do
Begin
A:=Buffer[i+8];
Data.KRData[KR].OKR[i+M*$5c]:=A;
end;
end;
End;
End;
//******************************
KolParNastrA:=strtoint(SKRseting.KRSet.KR[KR].AOKol);
k:=0;
If KolParNastrA>0 then //Читаем A0
begin
KolParNastr14A:=KolParNastrA div 14;
KolParNastr14AOst:=KolParNastrA mod 14;
KRDataQueryByf[$06]:=$04;
for Param:=1 to KolParNastr14A do begin //поочерёдно читаем параметры пакетами по 14 штук
KRDataQueryByf[$07]:=$0E;
KRDataQueryByf[$02]:=$2D; //Количество байт
KRDataQueryByf[$03]:=$00; //отправляемых
for j:=1 to 14 do
begin
KRDataQueryByf[j*3+5]:=(strtoint(SKRseting.KRSet.KR[KR].AO[14*k+j,1]) and $FF); //начало номера алгоблока
KRDataQueryByf[j*3+6]:=(strtoint(SKRseting.KRSet.KR[KR].AO[14*k+j,1]) shr 8); //конец номера алгоблока
KRDataQueryByf[j*3+7]:=strtoint(SKRseting.KRSet.KR[KR].AO[14*k+j,2]); //номер входа алгоблока
end;
k:=k+1;
KRDataQueryByf[$32]:=crc8(0,49,KRDataQueryByf); //Считаем CRC
LenSav:=$79; //Считаем сколько должно придти
LenRec:=LenSav;
i:=0; //Сохраняем резервную копию(чтоб второй раз не считать)
Client1.WriteBuffer(KRDataQueryByf[$00], $33);
try
Client1.ReadBuffer(buffer[i],lenSav);
except
Oshibka:=True;
end;
i:=CRC8 (0,$78,buffer); //Считаем CRC
If buffer[$78]=i then //Проверяем CRC
begin
If (buffer[4] and $02)=1 then Rezerv:=true;
for i:=0 to 111 do
Begin
A:=Buffer[i+8];
Data.KRData[KR].AO[i+k*112]:=A;
end;
end;
end;
end; //Закончили читать ПАкеты AO
//*****************
If KolParNastr14Aost>0 then
begin //''4''
KRDataQueryByf[$07]:=KolParNastr14Aost;
KRDataQueryByf[$02]:=KolParNastr14Aost*3+3; //Количество байт
KRDataQueryByf[$03]:=$00; //отправляемых
KRDataQueryByf[$06]:=$04;
for j:=1 to KolParNastr14Aost do
begin
KRDataQueryByf[j*3+5]:=(strtoint(SKRseting.KRSet.KR[KR].AO[14*k+j,1]) and $FF); //начало номера алгоблока
KRDataQueryByf[j*3+6]:=(strtoint(SKRseting.KRSet.KR[KR].AO[14*k+j,1]) shr 8); //конец номера алгоблока
KRDataQueryByf[j*3+7]:=strtoint(SKRseting.KRSet.KR[KR].AO[14*k+j,2]); //номер входа алгоблока
end;
k:=k+1;
KRDataQueryByf[KolParNastr14Aost*3+8]:=crc8(0,KolParNastr14Aost*3+8,KRDataQueryByf); //Считаем CRC
LenSav:=KolParNastr14Aost*8+9; //Считаем сколько должно придти
LenRec:=LenSav;
i:=0; //Сохраняем резервную копию(чтоб второй раз не считать)
Client1.WriteBuffer(KRDataQueryByf[$00], KolParNastr14Aost*3+9);
try
Client1.ReadBuffer(buffer[i],lenSav);
except
Oshibka:=True;
end;
i:=CRC8 (0,LenRec-1,buffer); //Считаем CRC
If buffer[LenRec-1]=i then //Проверяем CRC
begin
for i:=0 to KolParNastr14Aost*8 do
Begin
If (buffer[4] and $02)=1 then Rezerv:=true;
A:=Buffer[i+8];
Data.KRData[KR].AO[i+k*112]:=A;
end;
end;
end; //Закончили читать остатки AO
//*****************************
If Data.KRData[KR].KolCom>0 Then
Begin
s:=True;
While s do begin
if Data.KRData[KR].Flag then sleep(1) else begin
Data.KRData[KR].Flag:=True;
For P:=0 to Data.KRData[KR].KolCom-1 do begin
For N:=0 to Data.KRData[KR].COM[P,2]+6 do KRDataQueryByf[n]:=Data.KRData[KR].COM[P,n];
LenSav:=$0A; //Считаем сколько должно придти
LenRec:=LenSav;
i:=0; //Сохраняем резервную копию(чтоб второй раз не считать)
Client1.WriteBuffer(KRDataQueryByf[$00], $0F);
try
Client1.ReadBuffer(buffer[i],lenSav);
except
Oshibka:=True;
end;
i:=CRC8 (0,LenRec-1,buffer); //Считаем CRC
If (buffer[LenRec-1]<>i) or (Buffer[$07]+Buffer[$08]<>0) then //Проверяем CRC и ответ
begin
If (buffer[4] and $02)=1 then Rezerv:=true;
Form1.Label1.Caption:='Ошибка отправки данных в контроллер';
end; //''6''
Data.KRData[KR].KolCom:=$00;
end;
Data.KRData[KR].Flag:=False;
s:=False;
end;
end;
end;
//*****************************
//SKR.TimeKolIter:=SKR.TimeKolIter+1;
//Form1.Label3.Caption:=IntToStr(SKR.TimeKolIter);
If Rezerv then begin
data.Potok.KRRezerv[KR]:=true;
break;
end;
if Oshibka then break;
end; //Повтор
data.Potok.KRWork[KR]:=false;
Client1.Disconnect;
Client1.Destroy;
//Form1.ListBox1.Items.Add('Вышебло на '+IntToStr(SKR.TimeKolIter));
//Form1.Timer1.Enabled:=True;
end;
function crc8 (Start, UsDataLen: integer; Mes: array of byte): byte;
var
i:word;
CR : cardinal;
begin
CR:=0;
for i:=Start to UsDataLen-1 do
begin
CR:=CR+Mes[i];
CR:= (CR and $FF) + (CR shr 8);
end;
CR:=(CR and $FF) + (CR shr 8);
CR:= not CR + $01;
CRC8:=CR and $FF;
end;
end.
[/more]