|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Senior Member
Iscritto dal: Apr 2000
Messaggi: 382
|
Windows CE - Aiuto Socket
Salve a tutti, desidererei chiedere il vostro aiuto per questa questione. Sto sviluppando un software di controllo in real-time su Windows CE 6.0.
Esso si compone di diversi thread, in cui uno di questo gestisce la comunicazione di rete. Uso le MessageQueue come metodo d’intercomunicazione tra thread. Al momento l’applicativo da me sviluppato funziona egregiamente, a parte la comunicazione bidirezionale attraverso la rete. Fino ad ora, nel thread che gestisce la comunicazione, eseguivo il seguente codice, in altre parole ricevevo i comandi da un socket TCP riuscendo a gestire eventuali disconnessioni: while(1) { if (stateCommunication) { receiveCommand(); } else { waitForConnection(); } } All’interno della funzione receiveCommand() richiamavo la recv() e successivamente procedevo all’elaborazione del comando ricevuto. Ora mi ritrovo con il problema che la recv() blocca l’esecuzione del programma fintanto che non arriva un nuovo comando. Al fine di risolvere questo problema ho provato ad inserire le seguenti istruzioni, con l’intenzione di non eseguire la rev() in presenza di un timeout, ma senza alcun risultato. FD_ZERO(&fdread); FD_SET(remoteSocket, &fdread); if (select(NULL,&fdread,NULL,NULL,&timeSelect)>0) { (…) } oltre che a: FD_ZERO(&fdread); FD_SET(remoteSocket, &fdread); if (FD_ISSET(remoteSocket,&fdread)) { (…) } e: unsigned long socketBlock=1; (…) if (ioctlsocket(remoteSocket,FIONBIO,&socketBlock)==0) { (…) } Come potrei risolvere? Avrei pensato alla seguente strategia: ovvero scomporre la ricezione e l’invio di dati in due thread opportunamente accordati dal thread principale di comunicazione, mediante una MessageQueue bidirezionale. Potrebbe essere una strategia vincente, anche al fine di limitare i ritardi tra invio e processo dei comandi, o solamente un inutile spreco di risorse?
__________________
MacBook Pro Retina iPhone 4S 16GB Ultima modifica di SimonJ : 04-11-2010 alle 10:56. |
|
|
|
|
|
#2 |
|
Senior Member
Iscritto dal: Mar 2009
Messaggi: 753
|
Ciao, vedo che vai a settare il socket come non-bloccante.
Ma questo lo fai contemporaneamente a select()? Io ho risolto problemi di questo tipo utilizzando select() e recv() bloccante. Utilizzando appunto un timeout. Ad esempio avevo utilizzato questa configurazione per gestire una quantità di dati in arrivo che non è conosciuta a priori... il ciclo esce quando il socket viene chiuso correttamente, oppure allo scadere di un timeout. Codice:
// Response
while(1) {
FD_ZERO(&readfd);
FD_SET(sock,&readfd);
if((RetVal = select(NULL,&readfd,NULL,NULL,&tv)) == 0) {
cerr << "Error: select() timeout" << endl; // Timeout on recv
return(ERROR_CODE);
}
else if (RetVal == SOCKET_ERROR) {
cerr << "Error: " << WSAGetLastError() << endl;
return(ERROR_CODE);
}
if(FD_ISSET(sock,&readfd)) {
RetVal = recvfrom(sock,response,RECV_BUF-1,0,(struct sockaddr*)&server,(int*)&size_addr);
if(RetVal == SOCKET_ERROR) { // Error
cerr << "Error: " << WSAGetLastError() << endl;
return(ERROR_CODE);
}
if(RetVal == 0) break; // Grateful close
}
cout << response;
memset(response,0,RECV_BUF);
}
Perchè se io non capito male, impostando la recv() non bloccante questa ritorna subito, troppo velocemente senza dati.... |
|
|
|
|
|
#3 |
|
Senior Member
Iscritto dal: Apr 2000
Messaggi: 382
|
No, non ho settato il socket come non bloccante ed utilizzato la select(): prima una prova, poi l'altra..
__________________
MacBook Pro Retina iPhone 4S 16GB |
|
|
|
|
|
#4 |
|
Senior Member
Iscritto dal: Mar 2009
Messaggi: 753
|
|
|
|
|
|
|
#5 |
|
Senior Member
Iscritto dal: Apr 2000
Messaggi: 382
|
Praticamente, select() non mi va mai a 0, mi restitisce sempre -1; ho impostato il timeout sia a 1s, 500ms, ecc..
__________________
MacBook Pro Retina iPhone 4S 16GB Ultima modifica di SimonJ : 04-11-2010 alle 13:44. |
|
|
|
|
|
#6 |
|
Senior Member
Iscritto dal: Apr 2000
Messaggi: 382
|
Ho fatto un "Pulisci soluzione" ed un "Rigenera soluzione" ed ora il select() sembra funzionare!
Il problema, ora, è che la prima recv() mi restituisce -1, facendo andare il software in attesa di un'altra connessione..
__________________
MacBook Pro Retina iPhone 4S 16GB Ultima modifica di SimonJ : 04-11-2010 alle 14:04. |
|
|
|
|
|
#7 |
|
Senior Member
Iscritto dal: Mar 2009
Messaggi: 753
|
... prova a capire di che si tratta con GetLastError().
|
|
|
|
|
|
#8 |
|
Senior Member
Iscritto dal: Apr 2000
Messaggi: 382
|
Mi restituisce l'errore 10038 (WSAENOTSOCK-socket operation on non-socket)..
__________________
MacBook Pro Retina iPhone 4S 16GB |
|
|
|
|
|
#9 |
|
Senior Member
Iscritto dal: Apr 2000
Messaggi: 382
|
Quest'ultimo errore era dovuto al fatto che non gestivo la condizione di ritorno a 0 di recv(). Per fortuna ora tutto va! Grazie ancora!
Un po' mi secca per le ore perse, quando bastava una semplice ricompilazione..strano, però..
__________________
MacBook Pro Retina iPhone 4S 16GB |
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 18:35.




















