PDA

View Full Version : [C] Esercizio programmazione di rete


nicolo_conte
02-04-2007, 12:57
Ciao a tutti,
devo creare il seguente programma:


Progettare, codificare in linguaggio C e collaudare un programma eseguito da un processo padre SRV e da due processi server SRV_X (1 o 2).
Ciascun processo SRV_X gestisce un canale CNL_X tra se stesso e un cliente di verifica CLI_X. Il problema utilizza l’allegato ‘term.txt’:

1)SRV ha il ruolo di server studente e deve servire in parallelo due richieste di servizio da parte di due clienti di verifica diversi CLI_X.
2)SRV si pone in attesa di collegamento da parte dei processi CLI_X sulla porta TCP XXXXX.
3)Per una generica richiesta di connessione X, SVR_X utilizza il canale di rete CNL_X aperto con CLI_X per eseguire i processi seguenti:

a)SRV_X entra in un ciclo nel quale svolge le seguenti azioni:

I)Riceve da CLI_X, sul canale CNL_X, una sequenza di caratteri terminata dal carattere newline (‘\n’) e di lunghezza massima 5. Tale sequenza, convertita in formato numerico, rappresenta un indice IDX (vedi nota per la conversione).
II)Apre il file ‘term.txt’, ricevuto come allegato al testo del problema, legge il carattere alla posizione IDX e lo memorizza, quindi chiude il file. Il carattere letto, indicato nel seguito come CH_TERM, ha il significato di ‘terminatore’ per i messaggi successivi.
III)Riceve da CLI_X, sul canale CNL_X, una sequenza di caratteri CH_SEQ di lunghezza max 64, il cui ultimo carattere è il ‘terminatore’ CH_TERM precedentemente letto da file.
IV)Conta il numero di caratteri della sequenza CH_SEQ, compreso il carattere ‘terminatore’ CH_TERM.
V)Invia a CLI_X, sullo stesso canale CNL_X, il numero di caratteri ricevuti, compreso il carattere ‘terminatore’ CH_TERM (vedi nota per la conversione).

b)Il ciclo termina quando SRV_X legge dal file un carattere terminatore CH_TERM uguale a ‘q’.
c)Il processo SRV_X chiude il canale di rete CNL_X e termina.

4)Il processo SRV_X non attende il termine dei servizi, ma chiude il canale usato e termina.

Si tenga presente che:

I clienti di verifica CLI_X funzionano sempre correttamente.
I clienti di verifica CLI_X si aspettano di ricevere la corretta lunghezza della stringa inviata CH_SEQ.
Per la conversione di una sequenza di caratteri numerici nel corrispondente valore interno si utilizzi la funzione:
int atoi(char *str);

Il numero da inviare deve essere convertito in una sequenza di caratteri terminata da newline (‘\n’). Utilizzare per la conversione la funzione ‘sprintf’:

int sprintf(char *buffer, char *format, [argument, …]);

Per la conversione utilizzare come specificatore di formato la stringa “%d\n”.
Se i clienti di verifica CLI ricevono dati diversi da quelli attesi, essi chiudono il canale CNL e terminano immediatamente.


una volta compilato il programma nel laboratorio vi è un verificatore che "verifiuca" il corretto funzionamento del programma. Se riusciste a darmi una mano sarebbe un sollievo visto che ormai ci sto "sbattendo la testa" da una settimana! Che errori vi sono?

nicolo_conte
02-04-2007, 12:58
E questo è il codice da me scritto:


#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

#define PORT 4000
#define MAXCONN 5

void addr_initialize(struct sockaddr_in * pt, unsigned int TCP_port, unsigned int IP_addr){

pt->sin_family = AF_INET;
pt->sin_port = htons ((unsigned short int) TCP_port);
pt->sin_addr.s_addr = IP_addr;
}

int main (){

FILE *file; /*INIZIO DICHIARAZIONE VARIABILI*/
struct sockaddr_in server_addr, cli_addr;
int client_len = sizeof (cli_addr);
int sd, new_sd, i, u, m, pid, teminatore;
char ch_term [5], ch_recv[64], num_char[10]; /*FINE DICHIARAZIONE VARIABILI*/

addr_initialize (&server_addr, PORT, INADDR_ANY);
sd = socket (AF_INET, SOCK_STREAM, 0); /*CREAZIONE DEL SOCKET SD*/
bind (sd, (struct sockaddr *) &server_addr, sizeof (server_addr);
listen (sd, MAXCONN); /*SI PONE IN ATTESA DI EVENTUALI CONNESSIONI*/

for (i = 0; i < 2; i++){ /*ACCETTA DUE CONNESSIONI*/

new_sd = accept (sd, (struct sockaddr *) &client_addr, &client_len);

pid = fork (); /*ESECUZIONE DELLA FUNZIONE FORK*/

if (pid == 0){ /*PROCESSO FIGLIO*/

for (u = 0; ch_term [u] != '\n'; u++){ /*RICEVE UN CARATTERE ALLA VOLTA FINO A '\N'*/
recv (new_sd, ch_term [u], 1, 0); /* E LO IMMAGAZZINA IN CH_TERM*/
}

terminatore = atoi (ch_term); /*TRASFORMA IN INT CH_TERM*/

file = fopen ("~/term.txt", "r"); /*APRE IL FILE TERM.TXT IN SOLA LETTURA*/
fseek (file, terminatore, SEEK_SET); /*SI SPOSTA DI UN VALORE TERMINATORE NEL FILE*/
fscanf (...) /*COME LEGGO IL CARATTERE????*/

for (m = 0; ch_recv [m] != /*dal terminatore*/ || ch_term [m] != 'q'; m++){
recv (new_sd, ch_recv[m], 1, 0);
}

sprintf (num_char, "%d\n", m);

send (num_char, m, 10, 0);

close (new_sd);

exit (0);
}

else close (sd);
}
}

nicolo_conte
02-04-2007, 12:58
sono un pò titubante sul modo di ottenere il carattere dal file e soprattutto se i cicli che ho creato portano effettivamente a qualcosa! Grazie mille a tutti coloro che avranno la pazienza di aiutarmi :)