Так, всё. У меня глаза кровоточат этот тред читать. «Произвольную длину» (в пределах возможностей буфера), надеюсь, сделать не проблема?
#include <iostream.h>
#include <conio.h>
#include <dos.h> //sleep
#include <process.h>
#include <stdio.h>
#include <fstream.h>
#include <windows.h>
HANDLE hCom;
char Test[14]={'Я',' ','к','р','и','в','е','д','к','о','!','!','!',3};
int InitCom(const char *Comm, int Baud)
{
DCB dcb;
COMMTIMEOUTS TO;
BOOL fSuccess;
hCom = CreateFile(Comm, GENERIC_READ | GENERIC_WRITE,
0, // comm devices must be opened w/exclusive-access
NULL, // no security attrs
OPEN_EXISTING, // comm devices must use OPEN_EXISTING
0, // not overlapped I/O
NULL // hTemplate must be NULL for comm devices
);
if (hCom == INVALID_HANDLE_VALUE)
{
return 0;
}
GetCommState(hCom,&dcb);
dcb.BaudRate = Baud;
dcb.ByteSize = 8;
dcb.Parity = NOPARITY;
dcb.StopBits = ONESTOPBIT;
fSuccess = SetCommState( hCom, &dcb);
if(!fSuccess) return 0; // fail
PurgeComm(hCom,PURGE_TXCLEAR|PURGE_RXCLEAR);
GetCommTimeouts( hCom,&TO);
TO.ReadIntervalTimeout=MAXDWORD; //This magic combiantion means "return received data only";
TO.ReadTotalTimeoutMultiplier=0;
TO.ReadTotalTimeoutConstant=0;
SetCommTimeouts( hCom,&TO);
return 1;
}
char Buffer[16]={0}; //null-term for cout
int ReceivedSoFar=0;
int ReceiveData()
{
unsigned long ActualSize;
int i;
ReadFile(hCom,Buffer+ReceivedSoFar,14-ReceivedSoFar,&ActualSize,NULL);
cout<<"trying to get remaining "<<14-ReceivedSoFar<<" bytes"<<endl;
if (!ActualSize) return 0;
cout<<"got "<<ActualSize<<" bytes"<<endl;
ReceivedSoFar+=ActualSize;
cout<<ReceivedSoFar<<" bytes total"<<endl;
if (ReceivedSoFar==14)
{
for (i=12; i>=0; i--) if (Buffer[i]==3)
{
cout<<"error -- end marker on byte "<<i<<" instead of 13th"<<endl;
memmove(Buffer, Buffer+i+1, ReceivedSoFar=(14-i-1));
cout<<ReceivedSoFar<<" bytes after error is probably OK"<<endl;
return -1; //end marker is in wrong place -- some bytes of prev. packet were lost
}
ReceivedSoFar=0; //starting a new packet
if (Buffer[13]!=3) return -1;
cout<<"packet is OK"<<endl;
return 1; //fully received
}
cout<<"packet is not complete yet"<<endl;
return 0; //partially received
}
void main (int argc, char *argv[])
{
char i,o,name[]="COM1";
unsigned long ret;
int speed=115200;
if (argc == 2) speed = atoi (argv[1]);
for (name[3]='9';name[3]>'0';name[3]--) if (InitCom (name, speed))
{
cout<<"COMM Port found on "<<name<<endl;
break;
}
// WriteFile(hCom,Test ,10,&ret,NULL); //Раскомментировать для совсем испорченного пакета.
// WriteFile(hCom,Test+7, 7,&ret,NULL); //Раскомментировать для испорченного пакета, который можно отделить от второго (нормального).
WriteFile(hCom,Test ,14,&ret,NULL); //Сами себе в loopback cable вместо контроллера;
for (i=0; i!='Y'&&i!='y'; cin>>i) cout<<"Check now?"<<endl;
switch (ReceiveData())
{
case -1: cout<<"Error!"<<endl; break;
case 0: cout<<"Not ready yet!"<<endl; break;
case 1: cout<<Buffer<<endl; break;
}
for (i=0; i!='Y'&&i!='y'; cin>>i) cout<<"Check again?"<<endl;
switch (ReceiveData())
{
case -1: cout<<"Error!"<<endl; break;
case 0: cout<<"Not ready yet!"<<endl; break;
case 1: cout<<Buffer<<endl; break;
}
for (i=0; i!='Y'&&i!='y'; cin>>i) cout<<"Y to exit"<<endl;
}