PDA

View Full Version : [c]=progetto socket


mercury841
27-06-2006, 20:31
Ragazzi devo fare questo progetto:

Shell Remota
Si realizzi un programma client/server che, tramite socket del dominio AF INET, permetta di eseguire i
comandi unix sotto riportati dalla macchina server a partire dalla macchina su cui é in esecuzione il
client.

I comandi da implementare sono almeno i seguenti:
-cp <path> <path> - Copia un file (regolare) da <path> a <path>
-ls <path> - Lista il contenuto della directory <path>
-rm <path> - Cancella il file individuato da <path>
-mkdir <path> - Crea la directory individuata da <path>

i comandi devono essere lanciati dalla macchina client insieme con i relativi argomenti, devono essere
eseguiti sulla macchina server e riportare il risultato dell’esecuzione sulla macchina client.

Secondo voi sono presenti delle sezioni critiche da gestire?
Ciao e grazie a chi mi aiuta.

wisher
28-06-2006, 08:49
secondo me si potrebbe fare utilizzando la exec sul server e poi (nn so se possibile ma credo di si) reindirizzando lo stdout del comando eseguito direttanente sul socket

trallallero
28-06-2006, 09:29
Ragazzi devo fare questo progetto:

Shell Remota
Si realizzi un programma client/server che, tramite socket del dominio AF INET, permetta di eseguire i
comandi unix sotto riportati dalla macchina server a partire dalla macchna su cui é in esecuzione il
client.

I comandi da implementare sono almeno i seguenti:
?-cp <path> <path> - Copia un file (regolare) da <path> a <path>
?-ls <path> - Lista il contenuto della directory <path>
?-rm <path> - Cancella il file individuato da <path>
-mkdir <path> - Crea la directory individuata da <path>

i comandi devono essere lanciati dalla macchina client insieme con i relativi argomenti, devono essere
eseguiti sulla macchina server e riportare il risultato dell'esecuzione sulla macchina client.

Secondo voi sono presenti delle sezioni critiche da gestire?
Ciao e grazie a chi mi aiuta.
fare un client/server non é una cazzata ;)
conosci la fork(), execvp(), etc() etc() etc() ? :D

devi creare un socket con socket(AF_INET, SOCK_STREAM, 0)
settare le opzioni con setsockopt(...) chiamare la bind(...)
la listen(...) se tutto é OK il server si deve clonare con la fork()
poi eventualmente modificare i parametri e passarli alla execvp(...).
E dopo viene il difficile :D

in bocca al lupo :)

mercury841
28-06-2006, 10:11
Di quello che avete detto già ho fatto tutto, a me interessava sapere solo se, secondo voi, facendo un sistema multiclient c'era bisogno di gestire qualche sezione critica.

trallallero
28-06-2006, 10:57
Di quello che avete detto già ho fatto tutto, a me interessava sapere solo se, secondo voi, facendo un sistema multiclient c'era bisogno di gestire qualche sezione critica.
ah scusa allora. Qui spesso capita che si chieda tutto il programma bello e pronto :)
cosa intendi per sezione critica ?
hai messo la gestione segnali ?

Andlea
28-06-2006, 11:14
Di quello che avete detto già ho fatto tutto, a me interessava sapere solo se, secondo voi, facendo un sistema multiclient c'era bisogno di gestire qualche sezione critica.
Ora mi viene solo in mente di controllare il segnale che sblocca la accept

mercury841
28-06-2006, 11:30
cosa intendi per sezione critica ?
allora per sezione critica intendo una parte di codice nel quale un processo o un thread può modificare variabili comuni,scrivere in un file e così via.Quando un processo o un thread è in esecuzione nella propria sezione critica, non si deve consentire a nessun altro processo o thread di essere in esecuzione nella propria sezione critica. Nel mio caso ci potrebbero essere due client che cercano di eseguire due operazioni diverse sullo stesso file contemporaneamente, per esempio un client manda il comando "rm file1" e un altro client manda il comando "cp file1 copia_file1". Secondo voi devo gestire questa situazione cioè evitare che queste due operazioni vengano eseguite contemporaneamente oppure lascio le cose così come stanno?


hai messo la gestione segnali ?
Segnali per cosa?Che tipo di segnali?

mercury841
28-06-2006, 11:43
Ora mi viene solo in mente di controllare il segnale che sblocca la accept

come controllare il segnale che sblocca la accept?
cma grazie a tutti per l'aiuto.

Andlea
28-06-2006, 11:50
for(;;){
if((socket = accept(....)) < 0){
if(errno == EINTR) continue;
else {
perror("errore nella accept");
exit(1);
}
}

trallallero
28-06-2006, 12:01
Segnali per cosa?Che tipo di segnali?


Segnali quali sigquit, sigint ...
se tu prendi il pid del server e ci fai un bel kill -9 <pid>
nel server potresti intercettarlo ed agire di conseguenza.
Se viene ucciso il server prima dealloco la memoria,
chiudo i sockets, stampo "ciao" a video etc etc
poi esco, per esempio.


/* ------------------------------------ *\
PREPARA INTERCETTAZIONE SEGNALI.
\* ------------------------------------ */
static void SigInit(void)
{
enum sigTab // ENUMERAZIONE ARRAY DI STRUTTURE PER 'sigaction'.
{
sigCHLD
, sigQUIT
, sigINT
, sigPIPE
, OFFsignal
};

static struct sigaction s[OFFsignal];

s[sigQUIT].sa_sigaction = QuitFunction;
sigemptyset(&s[sigQUIT].sa_mask);
s[sigQUIT].sa_flags = NULL;
if (sigaction(SIGQUIT, &s[sigQUIT], 0))
ExitMsg(__LINE__ ,1 ,"sigaction:SIGQUIT");

s[sigINT].sa_sigaction = QuitFunction;
sigemptyset(&s[sigINT].sa_mask);
s[sigINT].sa_flags = NULL;
if (sigaction(SIGINT, &s[sigINT], 0))
ExitMsg(__LINE__ ,1 ,"sigaction:SIGINT");

s[sigPIPE].sa_sigaction = PipeHandler;
sigemptyset(&s[sigPIPE].sa_mask);
s[sigPIPE].sa_flags = NULL;
if (sigaction(SIGPIPE, &s[sigPIPE], 0))
ExitMsg(__LINE__ ,1 ,"sigaction:SIGPIPE");
}

questo é la gestione dei segnali di un server che ho fatto anni fa.
Gestisco i segnali quit, interrupt e pipe.
Quando arriva un segnale del genere viene chiamata la funzione
che gli dico io (QuitFunction o PipeHandler) che deve essere
fatta in un certo modo ... .sa_sigaction é un pointer a funzione
di un certo tipo:

void (*p)( int, siginfo_t *, void *)


Per la sezione critica non ti saprei dire. Non ho esperienza
a riguardo. Ma é interessante ... ci penso un pó :)
Ma calcola che non ho esperienza teorica che comunque serve,
sicuramente chi ha studiato all'universitá ti puó aiutare
con info piú precise ;)

mercury841
28-06-2006, 18:38
è sorto un problema, io per far esguire i comandi al server faccio una dup2 per ridirezionare l'output nella socket, e poi una execvp con il vettore dei comandi. Funziona per tutti i comandi tranne per uno, se voglio far eseguire il comando "rm -i nome_file", per prima cosa non mi scrive nella socket "rm: remove regular file `nome_file'?", ma poi nel caso volessi inviare dal client la risposta y come dovrei fare????????

mercury841
11-07-2006, 10:20
io per far esguire i comandi al server faccio una dup2 per ridirezionare l'output nella socket, e poi una execvp con il comando da eseguire. Funziona però, volevo chiedervi se secondo voi è meglio usare una popen reindirizzando l'output su un file e poi copiare il contenuto di questo file nella socket.Ciao

sottovento
11-07-2006, 11:44
io per far esguire i comandi al server faccio una dup2 per ridirezionare l'output nella socket, e poi una execvp con il comando da eseguire. Funziona però, volevo chiedervi se secondo voi è meglio usare una popen reindirizzando l'output su un file e poi copiare il contenuto di questo file nella socket.Ciao
Ciao,
direi che la dup() (o la dup2()) sono la soluzione migliore. In effetti ti dovrebbero risolvere anche il problema dell'output di rm -i.
Per quanto riguarda le sezioni critiche, il mio consiglio e' quello di non fare assolutamente niente.
I vantaggi sono la semplicita' di realizzazione (non devi far niente) ed il fatto che e' giusto cosi': nel caso un client impartisca il comando di rm su un file che e' in fase di copia, il sistema reagira' come se i comandi fossero impartiti da due console locali.

Per quanto riguarda la gestione dei segnali: hai il problema che se un client se ne va in modo non corretto (per esempio, va in crash), TCP/IP potrebbe non avvertirti. Non e' detto, infatti, che tu possa ricevere una notifica di una simile situazione.

Purtroppo questa situazione, se non la gestisci, ti porterebbe ad avere un processo/thread oppure un semplice descrittore sempre allocato per una risorsa che non esiste piu'.

In questo senso, gestire i segnali di kill potrebbe aiutarti ma non ti risolve il problema. Forse la cosa migliore (a patto di complicare il codice) e' di avere un messaggio di watchdog ("sei vivo?") che viaggia in entrambe le direzioni. Se non lo ricevi in tempo utile, chiudi tutto.

Buon lavoro
Sottovento

mercury841
11-07-2006, 12:25
e in che modo posso realizzare la funzione del watchdog? mandando un messaggio al client e vedendo se mi risponde?

sottovento
11-07-2006, 15:32
e in che modo posso realizzare la funzione del watchdog? mandando un messaggio al client e vedendo se mi risponde?
Beh, si.
Questa e' la soluzione che viene usata piu' frequentemente. Certo, se devi fare solo un esame, non complicarti troppo la vita. Chiudi solo in caso ti venga notificato un errore (per esempio, una chiamata quale read(), write(), accept() e via dicendo fallisce).

High Flying
Sottovento