Newsgroup: it.comp.lang.c
Titolo: Aiuto su socket ed affini

Ciao a tutti.
Avrei bisogno di un aiuto.
Attualmente sto lavorando con 4 apparati collegati ad una lan a cui accede anche un pc.
Tramite putty, apro 4 connessioni telnet a questi 4 apparati e periodicamente, tramite un comando, controllo lo stato degli apparati.
 
Il tutto potrbbe essere automatizzato tramite un programma C che, conoscendo gli indirizzi ip degli apparati e la parta di accesso, apra 4 socket verso gli apparati e sequenzialmente (magari con uno sleep che rallenti il tutto) interroghi gli apparati e mostri a video lo stato delle macchine.
 
In questo campo sono un apprendista stregone e quello che sono riuscito a fare lo ho trovato in rete.
 
Ho provato a fare un programma C che, sostanzialmente faccia le seguenti azioni
(l'ambiente di programmazione e' cygwin avendo la necessita' di lavorare con WinXP)
 
while(1)
{
openSocket1
sendMessage
receiveMessage
closeSocket1
print a video
 
openSocket2
sendMessage
receiveMessage
closeSocket2
print a video
 
 
.....
 
 
}
 
ma quando gira, dopo aver effettuato un giro completo, sostanzialmente si blocca.
 
Alla fine quindi LA DOMANDA:
Nella procedura che ho schematizzato sopra, esiste un qualche motivo che blocca l'esecuzione del programma e che per ignoranza non ho implementato
(per esempio una qualche pulizia di buffer di comunicazione, o qualcosa che magari sporco durante il primo ciclo e restando inquinato non funziona piu') oppure tramite la vostra esperienza vedete nell'implementazione schematizzata  qualcosa di errato da correggere?
 
Ho anche tentato ad aprire fuori ciclo i socket e nel ciclo effettuare solo scrittura/lettura ma non ha funzionato ugualmente.
 
Grazie

 [...]
 
receiveMessage, di default blocca fino a che non è disponibile qualcosa 
da leggere nel socket.
In particolare, se chiedi di leggere 100 bytes, la funzione non ritornerà 
fino a che non saranno disponibile esattamente 100 bytes.
 
Ci sono diversi modi per risolvere, ma dato che i socket non sono 
definiti nella libreria standard del C, forse un newsgroup su UNIX (se 
usi i socket BSD), o Windows è una scelta migliore.
 
Se per gli altri non è un problema, continua pure qui, postando qualche 
dettaglio del codice che usi.
 
 
 
Ciao  Manlio

 [..]
 
<snip>
 
O anche da uno script.
In shell, per ogni macchina farei un:
(echo password; echo "comando"; sleep 1; echo "quit") | telenet ipMacchina
per ogni macchina.
 
Su win non dovrebbe essere tanto diverso, anzi.
 
Ciao!

 
 
Ovviamente se ho sbagliato gruppo <<scusatemi>>, ero comunque in buona fede.


Ma dove si blocca ?
Se come suppongo è nella receiveMessage il man di linux su recv dice:
 
 
If no messages are available at the socket, the receive calls wait for a 
message to arrive, unless the socket is nonblocking (see fcntl(2)), in 
which case the value -1 is returned and the external variable errno is 
set to EAGAIN or EWOULDBLOCK. The receive calls normally return any data 
available, up to the requested amount, rather than waiting for receipt 
of the full amount requested.
 
 
 
 

 fede.
 
Dato che c'è poco traffico non credo sia un grosso problema.
Del resto molte delle interfacce POSIX/UNIX sono portabili a molti 
sistemi operativi, Windows incluso (anche sensa cygwin).
 
 
 
Ciao  Manlio


Aggiungerei che il protocollo telnet,proprio in quanto protocollo, non è 
un semplice send/receive fatto semplicemente di comando/risposta
Occorre ovviamente seguirne i dettami
Qui i dettami della rfc854:
http://tools.ietf.org/html/rfc854
 
 
Consiglierei di cercare qualche programmino d' esempio che usi il 
protocollo telnet oppure una libreria che lo implementa
 
 
 
 
 
 

 protocollo telnet oppure una libreria che lo implementa
 
Se davvero deve usare telnet, credo sia meglio che usi system per 
chiamare il programma telnet, oppure meglio usare spawn (che su cygwin 
dovrebbe essere più efficiente rispetto a fork/exec) per lanciare telnet 
come sotto processo ed interagire tramite stdin/stdout.
 
Non è banale (a meno che la semplice system non basti), ma implementare 
il protocollo telnet forse è ancora meno banale.
 
 
Ciao  Manlio

 [...]
 
 
Ciao  Manlio


Questo è un piccolo esempio in perl 
(
http://www.perlfect.com/articles/telnet.shtml
)
Credo che lo possa capire anche chi non conosce perl
 
use Net::Telnet;
$telnet = new Net::Telnet ( Timeout=>10,Errmode=>'die');
$telnet->open('
camel.perlfect.com
');
$telnet->waitfor('/login: $/i');
$telnet->print('bilbo');
$telnet->waitfor('/password: $/i');
$telnet->print('baggins');
$telnet->waitfor('/\$ $/i');
$telnet->print('who');
$output = $telnet->waitfor('/\$ $/i');
print $output;
 
sostanzialmente fa l' expect delle stringhe che gli servono, una volta 
ricevute invia la stringa voluta
 
 
 
 


Grazie a tutti per le risposte.
Adesso devo solo riflettere eu tutti gli spunti avuti.
Ho provato lo script shell e sembra funzionare. 
Realtivamente alla citazione del manuale di equinock, (nella schematizzazione del codice avevo scritto receviveMessage ma in effetti per scrivere e leggere sui socket uso le istruzioni read e write che non sono cosi' chiare in quanto di uso generale e non specifiche per i socket.
Comunque grazie a tutti.

 Adesso devo solo riflettere eu tutti gli spunti avuti.
 
Beh, anche imparare a quotare non sarebbe male, gia' che ci siamo.


Ok
Comunque la read chiama la recv (o receiveMessage) se il file descriptor 
è un socket
La differenza sta che con la recv si hanno piu opzioni, quindi con 
possibilità di maggior controllo