From 88d8a251947f948094d35de596feaf49e975f91b Mon Sep 17 00:00:00 2001 From: Simone Piccardi Date: Sat, 4 Dec 2004 16:08:27 +0000 Subject: [PATCH] Corretto titolo della sezione IPC, e iniziato a scrivere funzione generica per connettere un socket. --- ipc.tex | 6 ++--- sockctrl.tex | 25 +++++++++++++----- sources/sockconn.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 86 insertions(+), 10 deletions(-) create mode 100644 sources/sockconn.c diff --git a/ipc.tex b/ipc.tex index 4168b12..22d6e76 100644 --- a/ipc.tex +++ b/ipc.tex @@ -774,7 +774,7 @@ dello stesso non all'interno di uno stesso processo, ma fra processi distinti (torneremo su questa funzionalità in sez.~\ref{sec:xxx_fd_passing}). -\section{La comunicazione fra processi di System V} +\section{Il sistema di comunicazione fra processi di System V} \label{sec:ipc_sysv} Benché le pipe e le fifo siano ancora ampiamente usate, esse scontano il @@ -786,7 +786,7 @@ Per questo nello sviluppo di System V vennero introdotti una serie di nuovi oggetti per la comunicazione fra processi ed una nuova interfaccia di programmazione, che fossero in grado di garantire una maggiore flessibilità. In questa sezione esamineremo come Linux supporta quello che viene chiamato il -\textsl{Sistema di comunicazione inter-processo} di System V, cui da qui in +\textsl{Sistema di comunicazione fra processi} di System V, cui da qui in avanti faremo riferimento come \textit{SysV IPC} (dove IPC è la sigla di \textit{Inter-Process Comunication}). @@ -3226,7 +3226,7 @@ sez.~\ref{sec:ipc_sysv_shm} che possa restituisca i risultati via rete. -\section{La comunicazione fra processi di POSIX} +\section{Il sistema di comunicazione fra processi di POSIX} \label{sec:ipc_posix} Per superare i numerosi problemi del \textit{SysV IPC}, evidenziati per i suoi diff --git a/sockctrl.tex b/sockctrl.tex index 62fd3d7..b4b229e 100644 --- a/sockctrl.tex +++ b/sockctrl.tex @@ -1538,7 +1538,7 @@ nello stesso ordine in cui vengono inviati dal server DNS. In particolare nulla garantisce che vengano forniti prima i dati relativi ai servizi di un determinato protocollo o tipo di socket, se ne sono presenti di diversi. Se allora utilizziamo il nostro programma potremo verificare il risultato: -\begin{verbatim} +\begin{Verbatim} [piccardi@gont sources]$ ./mygetaddr -c gapil.truelite.it echo Canonical name sources2.truelite.it IPv4 address: @@ -1549,7 +1549,7 @@ IPv4 address: Indirizzo 62.48.34.25 Protocollo 17 Porta 7 -\end{verbatim} +\end{Verbatim} %$ Una volta estratti i risultati dalla \textit{linked list} puntata da @@ -1650,14 +1650,25 @@ indirizzi indicati dagli argomenti \param{host} e \param{serv} come stringhe terminate dal carattere NUL, a meno che queste non debbano essere troncate qualora la loro dimensione ecceda quelle specificate dagli argomenti \param{hostlen} e \param{servlen}. Sono comunque definite le due costanti -\const{NI\_MAXHOST} e \const{NI\_MAXSERV}\footnote{le due costanti sono - definite in \file{netdb.h} ed hanno rispettivamente il valore 1024 e 12.} -che possono essere utilizzate come limiti massimi. In caso di errore viene -restituito invece un codice che assume gli stessi valori illustrati in +\const{NI\_MAXHOST} e \const{NI\_MAXSERV}\footnote{in Linux le due costanti + sono definite in \file{netdb.h} ed hanno rispettivamente il valore 1024 e + 12.} che possono essere utilizzate come limiti massimi. In caso di errore +viene restituito invece un codice che assume gli stessi valori illustrati in tab.~\ref{tab:addrinfo_error_code}. A questo punto possiamo fornire degli esempi di utilizzo diretto della nuova -interfaccia, adottandola per rendere i nostri client +interfaccia, adottandola per le precedenti implementazioni del client e del +server per il servizio \textit{echo}; dato che l'uso delle funzioni (in +particolare di \func{getaddrinfo} è piuttosto complesso, prevedendo una +impostazione manuale dell'argomento \param{hints}, provvederemo una +interfaccia semplificata per i due casi visti finora, quello in cui si +specifica nel client un indirizzo remoto per la connessione al server, e +quello in cui si specifica nel server un indirizzo locale su cui porsi in +ascolto. + +La prima funzione è allora \func{sockconn}, che richiede la risoluzione di un +indirizzo e di un servizio per connettere un socket allo stesso. + \section{Le opzioni dei socket} diff --git a/sources/sockconn.c b/sources/sockconn.c new file mode 100644 index 0000000..c162474 --- /dev/null +++ b/sources/sockconn.c @@ -0,0 +1,65 @@ +/* sockconn.c + * + * Copyright (C) 2004 Simone Piccardi + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +/**************************************************************** + * + * Routine sockconn + * Return a connected socket given hostname, service, and socket type + * + * Author: Simone Piccardi + * Dec. 2004 + * + * $Id$ + * + ****************************************************************/ +#include +#include +#include +#include + +int sockconn(char *host, char *serv, int prot, int type) +{ + struct addrinfo hint, *addr; + int res; + int sock + /* initialize hint */ + memset(&hint, 0, sizeof(hint)); + hint.ai_family = PF_UNSPEC; + hint.ai_protocol = prot; + hint.ai_socktype = type; + res = getaddrinfo(host, serv, &hint, &addr); + if (res != 0) { + printf("sockconn cannot resolve host %s, service %s, + protocol %d: %s\n", host, serv, prot, gai_strerror(res)); + errno = 0; + return -1; + } + sock = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol); + if (sock < 0) { + perror("sockconn cannot create socket\n"); + return sock; + } + res = connect(sock, addr->ai_addr, addr->ai_addrlen); + if (res < 0) { + perror("sockconn cannot connect socket\n"); + return res; + } + freeaddrinfo(addr); + return sock; +} + -- 2.30.2