Corso di Laurea in Ing. Informatica, Universita' La Sapienza
Sistemi Operativi II
Docente Roberto Baldoni

Soluzione della domanda di programmazione (argomento: SOCKET - Appello del 22 Marzo 2004).

Il server FTP per ogni client mantiene due connessioni:

Quindi i passi da effettuare sono:

  1. creazione del processo/thread di gestione di un client;
  2. lettura dei comandi provenienti dal client;
  3. parsing dei comandi;
  4. se il comando è PORT XXX allora viene instaurata una nuova connessione col client sulla porta specifica;

Di seguito viene riportata la porzione di codice che implementa la funzionalità. Nel file zip è possibile scaricare il server e un client di prova.

		/*  Poniamo il socket in ascolto di eventuali connessioni */
		sin_size = sizeof(struct sockaddr_in);
		if ( (control_conn = accept(list_s, (struct sockaddr *)&their_addr, &sin_size) ) < 0 ) {
			fprintf(stderr, "server: errore durante la fase di accept.\n");								
			exit(EXIT_FAILURE);
		}

		if (!fork()) {
			close(list_s);
			Readline(control_conn, buffer, MAX_LINE-1);
			printf("server: il client ha scritto\n\t%s\n",buffer);
			fflush(stdout);
			if (strncmp(buffer,"PORT",4)==0) {

				// Creazione socket per canale dati /
				if ( (data_s = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) {
					fprintf(stderr, "server: errore durante la creazione della socket per canale dati.\n");
					exit(EXIT_FAILURE);
				}

				// Inizializzazione sockaddr_in con dati del client /
				strcpy(client_port, buffer + 5);
				printf("server: il client richiede una connessione dati verso la sua porta %s\n", client_port);
				memset(&client_addr, 0, sizeof(client_addr));
				client_addr.sin_family = AF_INET;
				client_addr.sin_port = htons(strtol(client_port, NULL, 0));
				client_addr.sin_addr = their_addr.sin_addr;

				// Connessione /
				if ( connect(data_s, (struct sockaddr *) &client_addr, sizeof(client_addr) ) < 0 ) {
					printf("server: errore durante l'apertura del canale dati verso il client.\n");
					exit(EXIT_FAILURE);
				}
				printf("server: la connessione dati e' stata aperta.\n");
				strncpy(buffer, "OK\n", strlen("OK\n"));
				Writeline(control_conn, buffer, strlen(buffer));
				
			}

			/* Chiudiamo i socket aperti */
			close(control_conn);
			close(data_s);
			exit(EXIT_SUCCESS);
		}
		
		close(control_conn);