Fonction api win32 ReadFile : lire trame de longueur inconnue?
Bonjour,
Je dois lire des trames d'octets sur le port série sans connaître la longueur de celles çi. Pour cela je fourni un buffer à la fontion ReadFile ainsi que sa taille. En utilisant le mode OVERLAPPED, je voudrais pouvoir réceptionner les trames sans attendre que le buffer soit plein (dans le cas où les trames sont moins longues que la taille du buffer, le cas pratique à priori :) ).
Voiçi mon code :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
|
int main(int argc, char* argv[])
{
HANDLE h;
DWORD result=0;
DWORD rdMask=0;
OVERLAPPED osReader = {0};
OVERLAPPED osWriter = {0};
char buff[] = "bonjour";
char buffR[50];
h = McxOpenInit("\\\\.\\COM3"); /* fonction qui ouvre le port de comm en mode overlap*/
if(h == INVALID_HANDLE_VALUE)
{
cout<<"erreur init"<<endl;
return (-1);
}
SetCommMask(h, EV_RXCHAR);
osReader.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
osWriter.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if ( osReader.hEvent == NULL || osWriter.hEvent == NULL )
{
// Error creating overlapped event; abort.
cout<<"erreur creation ev"<<endl;
return (-1);
}
/*envoie une chaine de test, un autre programme (avec un autre port com) recoie la chaîne et renvoit une réponse immédiate)*/
if(!WriteFile(h,buff, sizeof(buff), &result,&osWriter))
{
if(GetLastError() != ERROR_IO_PENDING)
{
cout<<"erreur de write"<<endl;
return (-1);
}
else
{
//attente écriture terminée
if( !GetOverlappedResult(h, &osReader, &result, true) )
{
cout<<"erreur overlap write"<<endl;
return (-1);
}
else
{
cout<<"chaine envoyee"<<endl;
}
}
}
/*lecture d'une chaine provenant du port série, on ne connait pas sa taille qui est à priori inférieure à la taille du buffer*/
if( !ReadFile(h, buffR, sizeof(buffR), &result, &osReader) )
{
if(GetLastError() != ERROR_IO_PENDING)
{
cout<<"erreur de read"<<endl;
return (-1);
}
else
{
if( !GetOverlappedResult(h, &osReader, &result, true) )
{
cout<<"erreur overlap write"<<endl;
return (-1);
}
else
{
buffR [result] = 0;
cout<<buffR<<endl;
}
}
}
else
{
//lecture immédiate
buffR [result] = 0;
cout<<buffR<<endl;
}
CloseHandle(h);
return 0;
} |
Ce programme fonctionne presque. Tant que le buffer "buffR" de réception n'est pas plein, le programme n'affiche pas la châine ( la fonction GetOverlappedResult bloque le programme). Je voudrais savoir si il est possible de récupérer directement un train d'octet sans attendre d'avoir lu autant de caractère que la taille du buffer de réception (50).
Je sais que c'est possible avec les sockets et la fonction recv dont l'appel se termine même si le buffer n'est pas plein et qui renvoie le nombre d'octet lu qui peut être inférieur à la taille de buffer.
Pour les services de fichier, pas moyen d'avoir le même comportement?
Merçi d'avance.