我用API函数实现了串口通讯功能,在接收数据的时候碰到了点问题。程序意图:利用某种机制(什么机制正是我想问的),保证接收到的帧在业务上是完整的。比如,程序预期应该收到“FE68AAAAAAAAAAAA68010243C3D516”,但调用ReadFile函数可能只取回了 “FE68AAAAAA”,如何判断是否需要再次调用ReadFile读串口缓存?说明:1、帧长度是不固定的
2、帧有格式,比如FE开头,16结尾。但在串口接收类里面,为了程序的通用性,我不想利用业务规则来判断帧是否完整。
接收代码如下:
//读取数据
function TComPort.ReadData(var sResultDate:string): Boolean;
var
o: TOverLapped;
lReadNum: DWORD;
inpurbuffer : array[0..1024] of byte;
Coms:Tcomstat;
cbNum:integer;
begin
if FhSerial = INVALID_HANDLE_VALUE then
begin
Result := False;
Exit;
end; lReadNum := 0;
Fillchar(o, Sizeof(o), 0);
o.hEvent := CreateEvent(nil, True, False, nil);//create an autoret Event object sResultDate:=''; cbNum:=Coms.cbInQue;
if not ReadFile(FhSerial, inpurbuffer, cbNum, lReadNum, @o) then
begin
if GetLastError() = ERROR_IO_PENDING then
begin
if WaitForSingleObject(o.HEvent, INFINITE) = WAIT_OBJECT_0 then
begin
if not GetOverlappedResult(FhSerial, o, lReadNum, False) then
begin
Result := False;
Closehandle(o.HEVent);
Exit;
end;
end
else begin
Result := False;
Closehandle(o.HEVent);
Exit;
end;
end;
end; CloseHandle(o.hEvent);
PurgeComm(FhSerial, PURGE_RXCLEAR or PURGE_TXCLEAR);//clear buffer
Result := True;
end;
2、帧有格式,比如FE开头,16结尾。但在串口接收类里面,为了程序的通用性,我不想利用业务规则来判断帧是否完整。
接收代码如下:
//读取数据
function TComPort.ReadData(var sResultDate:string): Boolean;
var
o: TOverLapped;
lReadNum: DWORD;
inpurbuffer : array[0..1024] of byte;
Coms:Tcomstat;
cbNum:integer;
begin
if FhSerial = INVALID_HANDLE_VALUE then
begin
Result := False;
Exit;
end; lReadNum := 0;
Fillchar(o, Sizeof(o), 0);
o.hEvent := CreateEvent(nil, True, False, nil);//create an autoret Event object sResultDate:=''; cbNum:=Coms.cbInQue;
if not ReadFile(FhSerial, inpurbuffer, cbNum, lReadNum, @o) then
begin
if GetLastError() = ERROR_IO_PENDING then
begin
if WaitForSingleObject(o.HEvent, INFINITE) = WAIT_OBJECT_0 then
begin
if not GetOverlappedResult(FhSerial, o, lReadNum, False) then
begin
Result := False;
Closehandle(o.HEVent);
Exit;
end;
end
else begin
Result := False;
Closehandle(o.HEVent);
Exit;
end;
end;
end; CloseHandle(o.hEvent);
PurgeComm(FhSerial, PURGE_RXCLEAR or PURGE_TXCLEAR);//clear buffer
Result := True;
end;
1、帧长度是不固定的
2、帧有格式,比如FE开头,16结尾。但在串口接收类里面,为了程序的通用性,我不想利用业务规则来判断帧是否完整。你只能通过判断"FE开头,16结尾"这一规则,才能够知道是否接收到了一个完整的帧。