Initial commit - Delphi MES client project
This commit is contained in:
@@ -0,0 +1,714 @@
|
||||
unit uTCPDevice;
|
||||
|
||||
interface
|
||||
|
||||
uses System.Win.ScktComp,uSafeLog,uErrorInfo,System.SysUtils,FMX.Types,
|
||||
System.StrUtils,System.Classes,WinSock,WinSock2,Winapi.Windows;
|
||||
|
||||
Const
|
||||
IOC_IN = $80000000;
|
||||
IOC_VENDOR = $18000000;
|
||||
IOC_out = $40000000;
|
||||
SIO_KEEPALIVE_VALS = IOC_IN or IOC_VENDOR or 4;
|
||||
DATA_BUFSIZE = 8192;
|
||||
|
||||
type
|
||||
TTCP_KEEPALIVE = packed record
|
||||
onoff: integer;
|
||||
keepalivetime: integer;
|
||||
keepaliveinterval: integer;
|
||||
end;
|
||||
|
||||
TWorkEvent = procedure(sValue:string) of object;
|
||||
T2DWorkEvent = procedure(Sender: TObject;sValue:string) of object;
|
||||
|
||||
TThreadX<T> = class(TThread)
|
||||
private
|
||||
FProc: TProc<T>;
|
||||
AValue:T;
|
||||
protected
|
||||
procedure Execute; override;
|
||||
public
|
||||
constructor Create(const AProc: TProc<T>;ProcPar:T);
|
||||
end;
|
||||
|
||||
TThreadHelper= class helper for TThread
|
||||
public
|
||||
class function CreateThreadX<T>(const ThreadProc: TProc<T>;proPar:T): TThread; static;
|
||||
end;
|
||||
|
||||
TRfid=class //RFID
|
||||
private
|
||||
bIsDestory:boolean;
|
||||
FOnWork:TWorkEvent;
|
||||
FOnShowState:TWorkEvent;
|
||||
FTimer: TTimer;
|
||||
FPreValue:string; //保存前一个标签值
|
||||
FSocket:TClientSocket;
|
||||
procedure TimerTimer(Sender: TObject); //判断连接状态,断开的话,自动重连
|
||||
procedure SocketRead(Sender: TObject; Socket: TCustomWinSocket); //读缓存数据
|
||||
procedure SocketError(Sender: TObject; Socket: TCustomWinSocket; //出错代码处理
|
||||
ErrorEvent: TErrorEvent; var ErrorCode: Integer);
|
||||
procedure SocketConnect(Sender: TObject; Socket: TCustomWinSocket);
|
||||
procedure SocketDisConnect(Sender: TObject; Socket: TCustomWinSocket);
|
||||
procedure SocketConnecting(Sender: TObject; Socket: TCustomWinSocket);
|
||||
procedure SendBtye(sValue: String);
|
||||
|
||||
public
|
||||
constructor Create(sIp:string;iPort:integer);
|
||||
destructor Destroy; override;
|
||||
procedure Close();
|
||||
procedure Connect();
|
||||
property OnWork: TWorkEvent read FOnWork write FOnWork;//业务处理事件
|
||||
property OnShowState:TWorkEvent read FOnShowState write FOnShowState;//显示连接断开提示
|
||||
procedure SendStr(sValue:String); //
|
||||
procedure ReadData;
|
||||
end;
|
||||
|
||||
TNumEnce=class //采集器
|
||||
private
|
||||
bIsDestory:boolean;
|
||||
FOnWork:TWorkEvent;
|
||||
FOnShowState:TWorkEvent;
|
||||
FTimer: TTimer;
|
||||
FPreValue:string; //保存前一个值
|
||||
FSocket:TClientSocket;
|
||||
FCount:Integer;
|
||||
procedure TimerTimer(Sender: TObject); //判断连接状态,断开的话,自动重连
|
||||
procedure SocketRead(Sender: TObject; Socket: TCustomWinSocket); //读缓存数据
|
||||
procedure SocketError(Sender: TObject; Socket: TCustomWinSocket; //出错代码处理
|
||||
ErrorEvent: TErrorEvent; var ErrorCode: Integer);
|
||||
procedure SocketConnect(Sender: TObject; Socket: TCustomWinSocket);
|
||||
procedure SocketDisConnect(Sender: TObject; Socket: TCustomWinSocket);
|
||||
procedure SocketConnecting(Sender: TObject; Socket: TCustomWinSocket);
|
||||
public
|
||||
|
||||
constructor Create(sIp:string;iPort:integer);
|
||||
destructor Destroy; override;
|
||||
procedure Close();
|
||||
procedure Connect();
|
||||
property OnWork: TWorkEvent read FOnWork write FOnWork;//业务处理事件
|
||||
property OnShowState:TWorkEvent read FOnShowState write FOnShowState;//显示连接断开提示
|
||||
property Count: Integer read FCount write FCount;
|
||||
Function Check(sValue:string;iPos:Integer):boolean; //判断返回字符串具体位为1还是0,返回真为1
|
||||
procedure SendStr(sValue:String);
|
||||
procedure SendStr8(sValue:String);
|
||||
end;
|
||||
|
||||
T2DCode=class //2D读头
|
||||
private
|
||||
bIsDestory:boolean;
|
||||
FTimer: TTimer;
|
||||
FOnWork:T2DWorkEvent;
|
||||
FOnShowState:TWorkEvent;
|
||||
FSocket:TClientSocket;
|
||||
FNum:Integer; //编号
|
||||
procedure SetKeepAlive(Socket: TCustomWinSocket);
|
||||
procedure TimerTimer(Sender: TObject); //判断连接状态,断开的话,自动重连
|
||||
procedure SocketRead(Sender: TObject; Socket: TCustomWinSocket); //读缓存数据
|
||||
procedure SocketError(Sender: TObject; Socket: TCustomWinSocket; //出错代码处理
|
||||
ErrorEvent: TErrorEvent; var ErrorCode: Integer);
|
||||
procedure SocketConnect(Sender: TObject; Socket: TCustomWinSocket);
|
||||
procedure SocketDisConnect(Sender: TObject; Socket: TCustomWinSocket);
|
||||
procedure SocketConnecting(Sender: TObject; Socket: TCustomWinSocket);
|
||||
public
|
||||
property Num:Integer read FNum write FNum;
|
||||
constructor Create(sIp:string;iPort:integer);
|
||||
destructor Destroy; override;
|
||||
procedure Close();
|
||||
procedure Connect();
|
||||
procedure DisConnect();
|
||||
property OnWork: T2DWorkEvent read FOnWork write FOnWork;//业务处理事件
|
||||
property OnShowState:TWorkEvent read FOnShowState write FOnShowState;//显示连接断开提示
|
||||
procedure Open;
|
||||
end;
|
||||
|
||||
|
||||
implementation
|
||||
|
||||
|
||||
|
||||
constructor TThreadX<T>.Create(const AProc: TProc<T>;ProcPar:T);
|
||||
begin
|
||||
inherited Create(True);
|
||||
FreeOnTerminate := True;
|
||||
FProc := AProc;
|
||||
Avalue:=ProcPar;
|
||||
end;
|
||||
|
||||
procedure TThreadX<T>.Execute;
|
||||
begin
|
||||
inherited;
|
||||
FProc(Avalue);
|
||||
end;
|
||||
|
||||
class function TThreadHelper.CreateThreadX<T>(const ThreadProc: TProc<T>; proPar: T): TThread;
|
||||
begin
|
||||
Result := TThreadX<T>.Create(ThreadProc,proPar);
|
||||
end;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
constructor TRfid.Create(sIp:string;iPort:integer); //参数固定
|
||||
begin
|
||||
inherited Create;
|
||||
bIsDestory:=false;
|
||||
WorkLog.Debug('创建RFID读卡器');
|
||||
FSocket:=TClientSocket.Create(nil);
|
||||
FSocket.OnRead:=SocketRead;
|
||||
FSocket.OnError:=SocketError;
|
||||
FSocket.OnConnect:=SocketConnect;
|
||||
FSocket.OnDisconnect:=SocketDisConnect;
|
||||
FSocket.OnConnecting:=SocketConnecting;
|
||||
FSocket.Address:=sIp;
|
||||
FSocket.Port:=iPort;
|
||||
FTimer:=TTimer.Create(nil);
|
||||
FTimer.OnTimer:=TimerTimer;
|
||||
FTimer.Enabled:=true;
|
||||
WorkLog.Debug('连接RFID读卡器:%s,%d',[sIp,iPort]);
|
||||
FPreValue:='';
|
||||
end;
|
||||
|
||||
procedure TRfid.Connect();
|
||||
var
|
||||
tmp:string;
|
||||
begin
|
||||
tmp:=Format('连接RFID读卡器:%s,%d',[FSocket.Address,FSocket.Port]);
|
||||
WorkLog.Debug(tmp);
|
||||
if Assigned(FOnShowState) then FOnShowState(tmp);
|
||||
FSocket.Active:=true;
|
||||
end;
|
||||
|
||||
procedure TRfid.SocketConnecting(Sender: TObject; Socket: TCustomWinSocket);
|
||||
begin
|
||||
WorkLog.Debug('RFID读卡器连接中...');
|
||||
if Assigned(FOnShowState) then FOnShowState('RFID读卡器连接中...');
|
||||
end;
|
||||
|
||||
procedure TRfid.Close();
|
||||
begin
|
||||
FTimer.Enabled:=false;
|
||||
FSocket.Close;
|
||||
end;
|
||||
|
||||
destructor TRfid.Destroy;
|
||||
begin
|
||||
bIsDestory:=true;
|
||||
FSocket.Close;
|
||||
FTimer.Enabled:=false;
|
||||
WorkLog.Debug('销毁RFID读卡器');
|
||||
FSocket.Free;
|
||||
FTimer.Free;
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
procedure TRfid.SocketDisConnect(Sender: TObject; Socket: TCustomWinSocket);
|
||||
begin
|
||||
WorkLog.Debug('RFID读卡器连接断开');
|
||||
if Assigned(FOnShowState) then FOnShowState('RFID读卡器连接断开');
|
||||
end;
|
||||
|
||||
procedure TRfid.TimerTimer(Sender: TObject);
|
||||
begin
|
||||
if FTimer.Enabled then
|
||||
begin
|
||||
FTimer.Enabled:=false;
|
||||
FSocket.Close;
|
||||
FSocket.Open;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TRfid.SocketRead(Sender: TObject; Socket: TCustomWinSocket);
|
||||
var
|
||||
buf:array[0..1024] of byte;
|
||||
sHexString:string;
|
||||
i:Integer;
|
||||
sData:string; //标签数据
|
||||
function ByteToString(const Value:PByte;iLen:Integer): String;
|
||||
var
|
||||
I: integer;
|
||||
S : String;
|
||||
begin
|
||||
S := '';
|
||||
for I := 0 to iLen-1 do
|
||||
begin
|
||||
S := S+Chr(Value[I]);
|
||||
end;
|
||||
Result := S;
|
||||
end;
|
||||
begin
|
||||
if bIsDestory then Exit;
|
||||
|
||||
sHexString:='';
|
||||
for i:= 0 to Socket.ReceiveBuf(buf,1024) do
|
||||
begin
|
||||
sHexString:=sHexString+buf[i].ToHexString;
|
||||
end;
|
||||
WorkLog.Debug('RFID读到数据:%s',[sHexString]);
|
||||
|
||||
//1B3501FF1F0012BE3800413346564646473246413033300000413346564646473246413033A41B3501FF03000100000100
|
||||
//数据包的第7位,代表包数据长度
|
||||
if (buf[0]=$1B) and ((buf[1]=$35) or (buf[1]=$39)) then // 1B 39 包头 (buf[1]=$39) and (buf[6]<20) and (buf[6]>8)
|
||||
begin
|
||||
sData:=ByteToString(@buf[10],buf[6]-3);
|
||||
if sData<>FPreValue then //判断重复
|
||||
begin
|
||||
if sData.Length>8 then//保证数据有效
|
||||
FPreValue:=sData;
|
||||
|
||||
//开启连接数据库线程
|
||||
if Assigned(FOnWork) then
|
||||
TThread.CreateThreadX<string>(FOnWork,sData).Start;
|
||||
WorkLog.Debug('RFID数据:%s',[sData]);
|
||||
end
|
||||
else
|
||||
WorkLog.Debug('RFID数据重复:%s',[sData]);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TRfid.SocketError(Sender: TObject; Socket: TCustomWinSocket;
|
||||
ErrorEvent: TErrorEvent; var ErrorCode: Integer);
|
||||
var
|
||||
tmpError:string;
|
||||
begin
|
||||
if (ErrorCode=10060) OR (ErrorCode=10065) then
|
||||
begin
|
||||
tmpError:=Format('RFID连接出错(%d):%s',[ErrorCode,SysErrorMessage(ErrorCode)]);
|
||||
if Assigned(FOnShowState) then FOnShowState('RFID连接失败,重新连接');
|
||||
end
|
||||
else
|
||||
begin
|
||||
tmpError:=Format('RFID连接出错(%d):%s',[ErrorCode,SysErrorMessage(ErrorCode)]);
|
||||
if Assigned(FOnShowState) then FOnShowState('RFID连接出错:'+SysErrorMessage(ErrorCode));
|
||||
end;
|
||||
workLog.Error('Rfid.SocketError:'+tmpError);
|
||||
ErrorCode:=0;
|
||||
FTimer.Enabled:=true;
|
||||
end;
|
||||
|
||||
procedure TRfid.SocketConnect(Sender: TObject; Socket: TCustomWinSocket);
|
||||
begin
|
||||
WorkLog.Debug('RFID连接成功');
|
||||
if Assigned(FOnShowState) then FOnShowState('RFID连接成功');
|
||||
end;
|
||||
|
||||
procedure TRfid.SendStr(sValue:String); //Send 1b 35 00 00 08 00 01 02 06 00 00 00 00 00 05
|
||||
VAR
|
||||
bBtye:array[0..6] of byte;
|
||||
i:integer;
|
||||
begin
|
||||
if bIsDestory or (Length(sValue)>7) then Exit;
|
||||
WorkLog.Debug(Format('下发指令Rfid:%s',[sValue]));
|
||||
|
||||
for I := 0 to Length(sValue)-1 do
|
||||
bBtye[i]:=Ord(sValue[i+1]);
|
||||
// bBtye[0]:=Ord(sValue[1]);bBtye[1]:=Ord(sValue[1]);bBtye[2]:=$31;
|
||||
// bBtye[3]:=$31;bBtye[4]:=$31;bBtye[5]:=$30;
|
||||
// bBtye[6]:=$30;
|
||||
FSocket.Socket.SendText(sValue);
|
||||
// FSocket.Socket.SendBuf(bBtye[0],Length(bBtye));
|
||||
// FSocket.Socket.SendText('#011300');
|
||||
|
||||
end;
|
||||
|
||||
procedure TRfid.SendBtye(sValue:String); //Send 1b 35 00 00 08 00 01 02 06 00 00 00 00 00 05
|
||||
VAR
|
||||
bBtye:array of byte;
|
||||
i,ilenNo:integer;
|
||||
begin
|
||||
if bIsDestory then Exit;
|
||||
WorkLog.Debug(Format('下发指令Rfid:%s',[sValue]));
|
||||
SetLength(bBtye,Length(sValue) div 2);
|
||||
ilenNo:= 0;
|
||||
for I := 1 to Length(sValue) do
|
||||
if i mod 2 =0 then
|
||||
begin
|
||||
bBtye[ilenNo]:=StrToInt('$'+sValue[i-1]+sValue[i]);
|
||||
inc(ilenNo);
|
||||
end;
|
||||
// bBtye[0]:=Ord(sValue[1]);bBtye[1]:=Ord(sValue[1]);bBtye[2]:=$31;
|
||||
// bBtye[3]:=$31;bBtye[4]:=$31;bBtye[5]:=$30;
|
||||
// bBtye[6]:=$30;
|
||||
// FSocket.Socket.SendText(sValue);
|
||||
FSocket.Socket.SendBuf(bBtye[0],Length(bBtye));
|
||||
// FSocket.Socket.SendText('#011300');
|
||||
|
||||
end;
|
||||
|
||||
procedure TRfid.ReadData();
|
||||
begin
|
||||
SendBtye('1b 35 00 00 08 00 01 02 06 00 00 00 00 00 05'.Replace(' ',''));
|
||||
end;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
constructor TNumEnce.Create(sIp:string;iPort:integer); //参数固定
|
||||
begin
|
||||
inherited Create;
|
||||
bIsDestory:=false;
|
||||
WorkLog.Debug('创建采集器');
|
||||
FSocket:=TClientSocket.Create(nil);
|
||||
FSocket.OnRead:=SocketRead;
|
||||
FSocket.OnError:=SocketError;
|
||||
FSocket.OnConnect:=SocketConnect;
|
||||
FSocket.OnDisconnect:=SocketDisConnect;
|
||||
FSocket.OnConnecting:=SocketConnecting;
|
||||
FSocket.Address:=sIp;
|
||||
FSocket.Port:=iPort;
|
||||
FTimer:=TTimer.Create(nil);
|
||||
FTimer.OnTimer:=TimerTimer;
|
||||
FTimer.Enabled:=true;
|
||||
WorkLog.Debug('连接采集器:%s,%d',[sIp,iPort]);
|
||||
FPreValue:='';
|
||||
FCount:=0;
|
||||
end;
|
||||
|
||||
procedure TNumEnce.Close();
|
||||
begin
|
||||
FTimer.Enabled:=false;
|
||||
FSocket.Close;
|
||||
end;
|
||||
|
||||
procedure TNumEnce.Connect();
|
||||
var
|
||||
tmp:string;
|
||||
begin
|
||||
tmp:=Format('连接采集器:%s,%d',[FSocket.Address,FSocket.Port]);
|
||||
WorkLog.Debug(tmp);
|
||||
if Assigned(FOnShowState) then FOnShowState(tmp);
|
||||
try
|
||||
FSocket.Active:=true;
|
||||
except
|
||||
WorkLog.error('NumEnce.Connect:'+'Connect()');
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TNumEnce.SocketConnecting(Sender: TObject; Socket: TCustomWinSocket);
|
||||
begin
|
||||
WorkLog.Debug('采集器连接中...');
|
||||
if Assigned(FOnShowState) then FOnShowState('采集器连接中...');
|
||||
end;
|
||||
|
||||
destructor TNumEnce.Destroy;
|
||||
begin
|
||||
bIsDestory:=true;
|
||||
FSocket.Close;
|
||||
FTimer.Enabled:=false;
|
||||
WorkLog.Debug('销毁采集器');
|
||||
FSocket.Free;
|
||||
FTimer.Free;
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
procedure TNumEnce.SocketDisConnect(Sender: TObject; Socket: TCustomWinSocket);
|
||||
begin
|
||||
WorkLog.Debug('采集器连接断开');
|
||||
if Assigned(FOnShowState) then FOnShowState('采集器连接断开');
|
||||
end;
|
||||
|
||||
procedure TNumEnce.TimerTimer(Sender: TObject);
|
||||
begin
|
||||
if FTimer.Enabled then
|
||||
begin
|
||||
FTimer.Enabled:=false;
|
||||
FSocket.Close;
|
||||
FSocket.Open;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TNumEnce.SocketRead(Sender: TObject; Socket: TCustomWinSocket);
|
||||
var
|
||||
buf:array[0..1024] of byte;
|
||||
sHexString:string;
|
||||
i:Integer;
|
||||
sData:string;
|
||||
function ByteToString(const Value:PByte;iLen:Integer): String;
|
||||
var
|
||||
I: integer;
|
||||
S : String;
|
||||
begin
|
||||
S := '';
|
||||
for I := 0 to iLen-1 do
|
||||
begin
|
||||
if Value[i]=$0D then break;
|
||||
S := S+Chr(Value[I]);
|
||||
end;
|
||||
Result := S;
|
||||
end;
|
||||
begin
|
||||
if bIsDestory then Exit;
|
||||
|
||||
sHexString:='';
|
||||
for i:= 0 to Socket.ReceiveBuf(buf,1024) do
|
||||
begin
|
||||
sHexString:=sHexString+buf[i].ToHexString;
|
||||
end;
|
||||
|
||||
|
||||
if (buf[0]=$3E) then // 3E 包头
|
||||
begin
|
||||
sData:=ByteToString(@buf[0],Length(sHexString) div 2-2); //18位
|
||||
if sData<>FPreValue then //判断重复
|
||||
begin
|
||||
FPreValue:= sData;
|
||||
WorkLog.Debug('采集器读到数据:%s',[sHexString]);
|
||||
if Assigned(FOnWork) then FOnWork(sData);
|
||||
//WorkLog.Debug('采集器数据:%s,计数:%d',[sData,FCount]);
|
||||
end;
|
||||
//else
|
||||
// WorkLog.Debug('RFID采集卡数据重复:%s',[sData]);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TNumEnce.SocketError(Sender: TObject; Socket: TCustomWinSocket;
|
||||
ErrorEvent: TErrorEvent; var ErrorCode: Integer);
|
||||
var
|
||||
tmpError:string;
|
||||
begin
|
||||
if (ErrorCode=10060) OR (ErrorCode=10065) then
|
||||
begin
|
||||
tmpError:=Format('采集器连接出错(%d):%s',[ErrorCode,SysErrorMessage(ErrorCode)]);
|
||||
if Assigned(FOnShowState) then FOnShowState('采集器连接失败,重新连接');
|
||||
end
|
||||
else
|
||||
begin
|
||||
tmpError:=Format('采集器连接出错(%d):%s',[ErrorCode,SysErrorMessage(ErrorCode)]);
|
||||
if Assigned(FOnShowState) then FOnShowState('采集器连接出错:'+SysErrorMessage(ErrorCode));
|
||||
end;
|
||||
workLog.Error('SocketError'+tmpError);
|
||||
ErrorCode:=0;
|
||||
FTimer.Enabled:=true;
|
||||
end;
|
||||
|
||||
procedure TNumEnce.SocketConnect(Sender: TObject; Socket: TCustomWinSocket);
|
||||
begin
|
||||
WorkLog.Debug('采集器连接成功');
|
||||
if Assigned(FOnShowState) then FOnShowState('采集器连接成功');
|
||||
end;
|
||||
|
||||
Function TNumEnce.Check(sValue:string;iPos:Integer):boolean;
|
||||
BEGIN
|
||||
if length(sValue)=18 then //判断返回位数为18位
|
||||
Result:=MidStr(sValue,(19-iPos),1)='1'
|
||||
else
|
||||
WorkLog.Error('采集器返回的数据异常');
|
||||
END;
|
||||
|
||||
procedure TNumEnce.SendStr8(sValue:String); //Send #011300
|
||||
VAR
|
||||
bBtye:array[0..7] of byte;
|
||||
i:integer;
|
||||
begin
|
||||
if bIsDestory or (Length(sValue)<8) then
|
||||
begin
|
||||
WorkLog.Error(Format('下发指令采集器错误:%s,%s,%s',[bIsDestory.ToString,Length(sValue).ToString,sValue]));
|
||||
Exit;
|
||||
end;
|
||||
for I := 0 to Length(sValue)-1 do
|
||||
bBtye[i]:=Ord(sValue[i+1]);
|
||||
// bBtye[0]:=Ord(sValue[1]);bBtye[1]:=Ord(sValue[1]);bBtye[2]:=$31;
|
||||
// bBtye[3]:=$31;bBtye[4]:=$31;bBtye[5]:=$30;
|
||||
// bBtye[6]:=$30;
|
||||
FSocket.Socket.SendText(sValue);
|
||||
// FSocket.Socket.SendBuf(bBtye[0],Length(bBtye));
|
||||
// FSocket.Socket.SendText('#011300');
|
||||
WorkLog.Debug(Format('下发指令采集器:%s',[sValue]));
|
||||
end;
|
||||
|
||||
procedure TNumEnce.SendStr(sValue:String); //Send #011300
|
||||
VAR
|
||||
bBtye:array[0..6] of byte;
|
||||
i:integer;
|
||||
begin
|
||||
if bIsDestory or (Length(sValue)<7) then
|
||||
begin
|
||||
WorkLog.Error(Format('下发指令采集器错误:%s,%s,%s',[bIsDestory.ToString,Length(sValue).ToString,sValue]));
|
||||
Exit;
|
||||
end;
|
||||
for I := 0 to Length(sValue)-1 do
|
||||
bBtye[i]:=Ord(sValue[i+1]);
|
||||
// bBtye[0]:=Ord(sValue[1]);bBtye[1]:=Ord(sValue[1]);bBtye[2]:=$31;
|
||||
// bBtye[3]:=$31;bBtye[4]:=$31;bBtye[5]:=$30;
|
||||
// bBtye[6]:=$30;
|
||||
FSocket.Socket.SendText(sValue);
|
||||
// FSocket.Socket.SendBuf(bBtye[0],Length(bBtye));
|
||||
// FSocket.Socket.SendText('#011300');
|
||||
WorkLog.Debug(Format('下发指令采集器:%s',[sValue]));
|
||||
end;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
constructor T2DCode.Create(sIp:string;iPort:integer); //参数固定
|
||||
begin
|
||||
inherited Create;
|
||||
bIsDestory:=false;
|
||||
FNum:=1;
|
||||
WorkLog.Debug('创建2D读头'+sIp+','+IntToStr(iPort));
|
||||
FSocket:=TClientSocket.Create(nil);
|
||||
FSocket.OnRead:=SocketRead;
|
||||
FSocket.OnError:=SocketError;
|
||||
FSocket.OnConnect:=SocketConnect;
|
||||
FSocket.OnDisconnect:=SocketDisConnect;
|
||||
FSocket.OnConnecting:=SocketConnecting;
|
||||
FSocket.Address:=sIp;
|
||||
FSocket.Port:=iPort;
|
||||
FTimer:=TTimer.Create(nil);
|
||||
FTimer.OnTimer:=TimerTimer;
|
||||
FTimer.Enabled:=false;
|
||||
end;
|
||||
|
||||
procedure T2DCode.Connect();
|
||||
var
|
||||
tmp:string;
|
||||
begin
|
||||
tmp:=Format('连接2D读头%d:%s,%d',[FNum,FSocket.Address,FSocket.Port]);
|
||||
WorkLog.Debug(tmp);
|
||||
if Assigned(FOnShowState) then FOnShowState(tmp);
|
||||
FSocket.Active:=true;
|
||||
end;
|
||||
|
||||
procedure T2DCode.DisConnect();
|
||||
begin
|
||||
FSocket.Close;
|
||||
FTimer.Enabled:=false;
|
||||
end;
|
||||
|
||||
procedure T2DCode.SocketConnecting(Sender: TObject; Socket: TCustomWinSocket);
|
||||
begin
|
||||
WorkLog.Debug(Format('2D读头%d连接中...',[FNum]));
|
||||
if Assigned(FOnShowState) then FOnShowState(Format('2D读头%d连接中...',[FNum]));
|
||||
end;
|
||||
|
||||
destructor T2DCode.Destroy;
|
||||
begin
|
||||
bIsDestory:=true;
|
||||
FSocket.Close;
|
||||
FTimer.Enabled:=false;
|
||||
WorkLog.Debug('销毁2D读头');
|
||||
FSocket.Free;
|
||||
FTimer.Free;
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
procedure T2DCode.SocketDisConnect(Sender: TObject; Socket: TCustomWinSocket);
|
||||
begin
|
||||
WorkLog.Debug(Format('2D读头%d连接断开',[FNum]));
|
||||
if Assigned(FOnShowState) then FOnShowState(Format('2D读头%d连接断开',[FNum]));
|
||||
end;
|
||||
|
||||
procedure T2DCode.SetKeepAlive(Socket: TCustomWinSocket);
|
||||
var
|
||||
opt:DWORD;
|
||||
klive, outKlive: TTCP_KEEPALIVE;
|
||||
i,j:integer;
|
||||
// OptVal: DWORD;
|
||||
begin
|
||||
opt := 1;
|
||||
if setsockopt(Socket.SocketHandle,SOL_SOCKET, SO_KEEPALIVE, PAnsiChar(@opt), SizeOf(opt)) = SOCKET_ERROR then
|
||||
begin
|
||||
//showInfo(Format('WinSock Error %d', [WSAGetLastError()]));
|
||||
end;
|
||||
klive.onoff := 1;
|
||||
klive.keepalivetime := 5000;
|
||||
klive.keepaliveinterval := 1;
|
||||
|
||||
if WSAIoctl(Socket.SocketHandle, SIO_KEEPALIVE_VALS, PAnsiChar(@klive),
|
||||
SizeOf(TTCP_KEEPALIVE), PAnsiChar(@outKlive),
|
||||
SizeOf(TTCP_KEEPALIVE), opt,0,nil) = SOCKET_ERROR then
|
||||
begin
|
||||
//showInfo(Format('WinSock Error %d', [WSAGetLastError()]));
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
procedure T2DCode.TimerTimer(Sender: TObject);
|
||||
begin
|
||||
if FTimer.Enabled then
|
||||
begin
|
||||
FTimer.Enabled:=false;
|
||||
FSocket.Close;
|
||||
FSocket.Open;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure T2DCode.SocketRead(Sender: TObject; Socket: TCustomWinSocket);
|
||||
var
|
||||
buf:array[0..1024] of byte;
|
||||
sHexString:string;
|
||||
i:Integer;
|
||||
sData:string;
|
||||
function ByteToString(const Value:PByte;iLen:Integer): String;
|
||||
var
|
||||
I: integer;
|
||||
S : String;
|
||||
begin
|
||||
S := '';
|
||||
for I := 0 to iLen-1 do
|
||||
begin
|
||||
if Value[i]=$0D then break;
|
||||
S := S+Chr(Value[I]);
|
||||
end;
|
||||
Result := S;
|
||||
end;
|
||||
begin
|
||||
if bIsDestory then Exit;
|
||||
|
||||
sHexString:='';
|
||||
for i:= 0 to Socket.ReceiveBuf(buf,1024) do
|
||||
begin
|
||||
sHexString:=sHexString+buf[i].ToHexString;
|
||||
end;
|
||||
WorkLog.Debug('2D读头%d读到数据:%s',[FNum,sHexString]);
|
||||
|
||||
sData:=ByteToString(@buf[0],Length(sHexString) div 2);
|
||||
if Assigned(FOnWork) then FOnWork(self,sData);
|
||||
end;
|
||||
|
||||
procedure T2DCode.SocketError(Sender: TObject; Socket: TCustomWinSocket;
|
||||
ErrorEvent: TErrorEvent; var ErrorCode: Integer);
|
||||
var
|
||||
tmpError:string;
|
||||
begin
|
||||
if (ErrorCode=10060) OR (ErrorCode=10065) then
|
||||
begin
|
||||
tmpError:=Format('2D读头%d连接出错(%d):%s',[FNum,ErrorCode,SysErrorMessage(ErrorCode)]);
|
||||
if Assigned(FOnShowState) then FOnShowState(Format('2D读头%d连接失败,重新连接',[FNum]));
|
||||
end
|
||||
else
|
||||
begin
|
||||
tmpError:=Format('2D读头%d连接出错(%d):%s',[FNum,ErrorCode,SysErrorMessage(ErrorCode)]);
|
||||
if Assigned(FOnShowState) then FOnShowState('2D读头连接出错:'+SysErrorMessage(ErrorCode));
|
||||
end;
|
||||
workLog.Error('2DCode.SocketError:'+tmpError);
|
||||
ErrorCode:=0;
|
||||
if bIsDestory then Exit;
|
||||
FTimer.Enabled:=true;
|
||||
end;
|
||||
|
||||
procedure T2DCode.SocketConnect(Sender: TObject; Socket: TCustomWinSocket);
|
||||
begin
|
||||
WorkLog.Debug(Format('2D读头%d连接成功',[FNum]));
|
||||
if Assigned(FOnShowState) then FOnShowState(Format('2D读头%d连接成功',[FNum]));
|
||||
end;
|
||||
|
||||
procedure T2DCode.Close; //4C4F46460D
|
||||
VAR
|
||||
bBtye:array[0..4] of byte;
|
||||
begin
|
||||
if bIsDestory then Exit;
|
||||
bBtye[0]:=$4C;bBtye[1]:=$4F;bBtye[2]:=$46;
|
||||
bBtye[3]:=$46;bBtye[4]:=$0D;
|
||||
fSocket.Socket.SendBuf(bBtye[0],5);
|
||||
WorkLog.Debug(Format('2D读头%d关闭',[FNum]));
|
||||
end;
|
||||
|
||||
procedure T2DCode.Open; //4C4F4E0d
|
||||
VAR
|
||||
bBtye:array[0..4] of byte;
|
||||
begin
|
||||
if bIsDestory then Exit;
|
||||
bBtye[0]:=$4C;bBtye[1]:=$4F;bBtye[2]:=$4E;
|
||||
bBtye[3]:=$0D;
|
||||
fSocket.Socket.SendBuf(bBtye[0],4);
|
||||
WorkLog.Debug(Format('2D读头%d打开',[FNum]));
|
||||
end;
|
||||
|
||||
end.
|
||||
Reference in New Issue
Block a user