Elem da se vratimo na kod:
Code:
o {
FD_ZERO(&rfds);
FD_SET(sockDesc, &rfds);
tv.tv_sec = 0;
tv.tv_usec = 50000;
retval = select(sockDesc + 1, &rfds, NULL, NULL, &tv);
if (retval) {
len += read(sockDesc, buf + len, 20000 - len);
}
} while ((buf[0] != 0x02) || (buf[len - 1] != 0x03));
Dakle, ovo je petlja. Tu select nema nikakvu svrhu. select ima svrhu samo onda kada osim citanja radis jos nesto dok cekas na input. Dakle ovde select moze da se izbaci.
Drugo da ti ne bih komplikovao da obrazlozim sta je ovde propust.
Pitanje buf[0] != 0x2. To. Dakle ako je buf[0] == 2 izlazi iz petlje i tu nastaje karambol. Zato sto nema garancije da je paket ceo procitan. Ako izbacis
to pitanje i ostavis samo buf[len-1] != 0x3 nece upadati u mrtvu petlju zato sto pretpostavimo da svaki kraj paketa zavrsava sa 0x3. Nema garancije
da neces procitati vise paketa, ali bar nece da uleti u mrtvu petlju.
E sad evo kako sam ja (netestirano) odradio, pa vidi, probaj, ne skodi ;)
Code:
~/.../bmaxa_data/examples >>> cat fwc.c
/* umesto ovoga
do {
FD_ZERO(&rfds);
FD_SET(sockDesc, &rfds);
tv.tv_sec = 0;
tv.tv_usec = 50000;
retval = select(sockDesc + 1, &rfds, NULL, NULL, &tv);
if (retval) {
len += read(sockDesc, buf + len, 20000 - len);
}
} while ((buf[0] != 0x02) || (buf[len - 1] != 0x03));
*/
// stavi ovo
std::string buf;
bool start=false;
char c=0;
while (true){
int rc = read(sockDesc,&c,1);
if (rc!=1){ // error process }
if (c == 0x2){
start = true;
buf.clear();
continue;
}
if (c == 0x3){ break; }
if (start) buf += c;
}
// len is buf.size()
Dakle citas karakter po karakter sve dok ne naletis na 0x3. Ono sto je interesantno je da hvatas pocetak, tj 0x2 znaci skipujes
ako si promasio pocetak.
string sam uzeo jer je tako jednostavnije nego sam da upucavas u neki bafer i bavis se time.