<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
		>
<channel>
	<title>Comments on: Come programmare le socket in ambienti GNU/Linux (Parte 1)</title>
	<atom:link href="http://www.oscene.net/it/programmazione/c/come-programmare-le-socket-in-ambienti-gnulinux/feed" rel="self" type="application/rss+xml" />
	<link>http://www.oscene.net/it/programmazione/c/come-programmare-le-socket-in-ambienti-gnulinux</link>
	<description>Ope(rating)n S(ystem)ource Scenario</description>
	<lastBuildDate>Sat, 04 Feb 2012 18:57:37 +0000</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
	<item>
		<title>By: Come programmare le socket in ambienti GNU/Linux (Parte 2) &#8211; OScene.net - Italiano</title>
		<link>http://www.oscene.net/it/programmazione/c/come-programmare-le-socket-in-ambienti-gnulinux/comment-page-1#comment-613</link>
		<dc:creator>Come programmare le socket in ambienti GNU/Linux (Parte 2) &#8211; OScene.net - Italiano</dc:creator>
		<pubDate>Wed, 20 Oct 2010 10:41:29 +0000</pubDate>
		<guid isPermaLink="false">http://www.oscene.net/it/?p=275#comment-613</guid>
		<description>[...] Come programmare le socket in ambienti GNU/Linux (Parte 2)  Ti interesser&amp;agrave anche...Come programmare le socket in ambienti GNU/Linux (Parte 1) Nel primo articolo abbiamo analizzato il funzionamento delle socket e di un server con rispettivo client. In questo vedremo un modo di programmare un tipico server concorrente utilizzando la funzione fork(). [...]</description>
		<content:encoded><![CDATA[<p>[...] Come programmare le socket in ambienti GNU/Linux (Parte 2)  Ti interesser&amp;agrave anche&#8230;Come programmare le socket in ambienti GNU/Linux (Parte 1) Nel primo articolo abbiamo analizzato il funzionamento delle socket e di un server con rispettivo client. In questo vedremo un modo di programmare un tipico server concorrente utilizzando la funzione fork(). [...]</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Saverio</title>
		<link>http://www.oscene.net/it/programmazione/c/come-programmare-le-socket-in-ambienti-gnulinux/comment-page-1#comment-606</link>
		<dc:creator>Saverio</dc:creator>
		<pubDate>Sun, 29 Aug 2010 16:11:21 +0000</pubDate>
		<guid isPermaLink="false">http://www.oscene.net/it/?p=275#comment-606</guid>
		<description>C&#039;e&#039; un modo per rifiutare tout court le connessioni se ce n&#039;e&#039; già una attiva?
Pur mettendo 1 come valore di queue della listen, comunque le connessioni sono accettate (temo che 5 sia il valore minimo nel mio ambiente). Il problema e&#039; che cio&#039; che il client manda, viene cachato, e mi arriva tutto assieme quando il client corrente si disconnette!!

Io ho bisogno di limitare ad una sola connessione (il server accetta comandi per un Servo), magari dando &quot;Busy, try later&quot; alle successive e chiudendo il soket.</description>
		<content:encoded><![CDATA[<p>C&#8217;e&#8217; un modo per rifiutare tout court le connessioni se ce n&#8217;e&#8217; già una attiva?<br />
Pur mettendo 1 come valore di queue della listen, comunque le connessioni sono accettate (temo che 5 sia il valore minimo nel mio ambiente). Il problema e&#8217; che cio&#8217; che il client manda, viene cachato, e mi arriva tutto assieme quando il client corrente si disconnette!!</p>
<p>Io ho bisogno di limitare ad una sola connessione (il server accetta comandi per un Servo), magari dando &#8220;Busy, try later&#8221; alle successive e chiudendo il soket.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Alessandro Iezzi</title>
		<link>http://www.oscene.net/it/programmazione/c/come-programmare-le-socket-in-ambienti-gnulinux/comment-page-1#comment-605</link>
		<dc:creator>Alessandro Iezzi</dc:creator>
		<pubDate>Sun, 08 Aug 2010 13:23:54 +0000</pubDate>
		<guid isPermaLink="false">http://www.oscene.net/it/?p=275#comment-605</guid>
		<description>@Antonio e @marco:
Si in effetti avrebbe più senso ciclare l&#039;invio.

@marco:
Sono felice che il commento ti sia stato utile, avevo paura di non essermi spiegato bene. Come accade spesso, molte cose purtroppo vengono tralasciate, ad esempio come quella del casting, non per dimenticanza ma proprio perché sarebbero un surplus.</description>
		<content:encoded><![CDATA[<p>@Antonio e @marco:<br />
Si in effetti avrebbe più senso ciclare l&#8217;invio.</p>
<p>@marco:<br />
Sono felice che il commento ti sia stato utile, avevo paura di non essermi spiegato bene. Come accade spesso, molte cose purtroppo vengono tralasciate, ad esempio come quella del casting, non per dimenticanza ma proprio perché sarebbero un surplus.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Antonio Barba</title>
		<link>http://www.oscene.net/it/programmazione/c/come-programmare-le-socket-in-ambienti-gnulinux/comment-page-1#comment-604</link>
		<dc:creator>Antonio Barba</dc:creator>
		<pubDate>Sun, 08 Aug 2010 10:49:52 +0000</pubDate>
		<guid isPermaLink="false">http://www.oscene.net/it/?p=275#comment-604</guid>
		<description>@marco:
Bene! :-)
Il problema comunque non è soltanto quello di computer con poca Ram, anche perchè grazie all&#039;address space virtuale puoi avere sempre 2GB di Ram &quot;virtuale&quot; anche con un PC a 32bit con 128MB di Ram fisica.
Il problema è che i moderni filesystem supportano file con dimensioni a 64bit, è quindi possibile (ed ormai anche comune) avere un file maggiore di 2GB (basti pensare all&#039;immagine ISO di un qualsiasi DVD), e quindi sarebbe fisicamente impossibile caricarlo in Ram su un sistema a 32 bit.
Ricordo che, sebbene 32 bit rappresentino lo spazio di 4 GB, metà di questo address space è riservato al kernel nella zona alta della memory map, quindi i programmi utente ne vedono solo 2 GB. Questo vale sia su Windows che Linux per x86. Il problema non si pone sulle versioni AMD64 (o meglio, il problema viene semplicemente rimandato più in là nel tempo).</description>
		<content:encoded><![CDATA[<p>@marco:<br />
Bene! <img src='http://www.oscene.net/it/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /><br />
Il problema comunque non è soltanto quello di computer con poca Ram, anche perchè grazie all&#8217;address space virtuale puoi avere sempre 2GB di Ram &#8220;virtuale&#8221; anche con un PC a 32bit con 128MB di Ram fisica.<br />
Il problema è che i moderni filesystem supportano file con dimensioni a 64bit, è quindi possibile (ed ormai anche comune) avere un file maggiore di 2GB (basti pensare all&#8217;immagine <acronym title="International Organization for Standardization">ISO</acronym> di un qualsiasi <acronym title="Digital Versatile Disc">DVD</acronym>), e quindi sarebbe fisicamente impossibile caricarlo in Ram su un sistema a 32 bit.<br />
Ricordo che, sebbene 32 bit rappresentino lo spazio di 4 <acronym title="Gigabyte">GB</acronym>, metà di questo address space è riservato al kernel nella zona alta della memory map, quindi i programmi utente ne vedono solo 2 <acronym title="Gigabyte">GB</acronym>. Questo vale sia su Windows che Linux per x86. Il problema non si pone sulle versioni AMD64 (o meglio, il problema viene semplicemente rimandato più in là nel tempo).</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: marco</title>
		<link>http://www.oscene.net/it/programmazione/c/come-programmare-le-socket-in-ambienti-gnulinux/comment-page-1#comment-603</link>
		<dc:creator>marco</dc:creator>
		<pubDate>Sun, 08 Aug 2010 10:39:29 +0000</pubDate>
		<guid isPermaLink="false">http://www.oscene.net/it/?p=275#comment-603</guid>
		<description>@Antonio Barba:
mi hai anticipato di qualche secondo :)
Per lo meno hai confermato la mia proposta. Ciao!</description>
		<content:encoded><![CDATA[<p>@Antonio Barba:<br />
mi hai anticipato di qualche secondo <img src='http://www.oscene.net/it/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /><br />
Per lo meno hai confermato la mia proposta. Ciao!</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: marco</title>
		<link>http://www.oscene.net/it/programmazione/c/come-programmare-le-socket-in-ambienti-gnulinux/comment-page-1#comment-602</link>
		<dc:creator>marco</dc:creator>
		<pubDate>Sun, 08 Aug 2010 10:38:07 +0000</pubDate>
		<guid isPermaLink="false">http://www.oscene.net/it/?p=275#comment-602</guid>
		<description>@Alessandro lezzi:
grazie per la delucidazione in merito al casting :)
Per quanto riguarda la domanda di Pietro, invece di utilizzare un unico buffer di dimensione pari al file da spedire non si potrebbe usarne uno di dimensione definita a priori e ciclare l&#039;invio dei dati &quot;un pezzo per volta&quot;? Così facendo si evita di sovraccaricare la memoria e si permette anche a computer con poca RAM di inviare file molto grandi.</description>
		<content:encoded><![CDATA[<p>@Alessandro lezzi:<br />
grazie per la delucidazione in merito al casting <img src='http://www.oscene.net/it/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /><br />
Per quanto riguarda la domanda di Pietro, invece di utilizzare un unico buffer di dimensione pari al file da spedire non si potrebbe usarne uno di dimensione definita a priori e ciclare l&#8217;invio dei dati &#8220;un pezzo per volta&#8221;? Così facendo si evita di sovraccaricare la memoria e si permette anche a computer con poca RAM di inviare file molto grandi.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Antonio Barba</title>
		<link>http://www.oscene.net/it/programmazione/c/come-programmare-le-socket-in-ambienti-gnulinux/comment-page-1#comment-601</link>
		<dc:creator>Antonio Barba</dc:creator>
		<pubDate>Sun, 08 Aug 2010 10:32:39 +0000</pubDate>
		<guid isPermaLink="false">http://www.oscene.net/it/?p=275#comment-601</guid>
		<description>@Alessandro e @Pietro:
per file piccoli (al di sotto del MB) si può optare per ingrandire il buffer, ad ogni modo la sizeof() non restituisce la dimensione del file (operazione fattibile soltanto a runtime), perchè è un operatore del linguaggio che viene risolto a compile time (non è una funzione).
Per sapere la dimensione di un file in bytes bisogna usare la funzione stat(), che restituisce tra le altre cose anche questa informazione.

Per file di dimensione arbitrariamente grande, la soluzione consiste nel leggere il file a &quot;chunk&quot; di grandezza fissata (ad esempio 1K alla volta), attraverso la funzione fread(), e inviare via socket questi chunk. 
Sia la trasmissione che la ricezione dovranno avvenire dentro un ciclo while, usando una variabile che conteggia i byte trasmessi/ricevuti, e ad ogni ciclo si dovrà effettuare una nuova fread/fwrite per leggere/scrivere quel chunk sul file.
E&#039; un&#039;operazione che comunque comporta tutta una serie di problemi dovuti alla scarsa affidabilità del mezzo di trasmissione, pertanto è meglio affidarsi a protocolli già sperimentati come FTP, che consentono anche il reinvio di chunk perduti, e il riordino degli stessi in caso di arrivo &quot;in ordine sparso&quot;, evento che si verifica frequentemente  su grandi reti come internet.</description>
		<content:encoded><![CDATA[<p>@Alessandro e @Pietro:<br />
per file piccoli (al di sotto del <acronym title="Megabyte">MB</acronym>) si può optare per ingrandire il buffer, ad ogni modo la sizeof() non restituisce la dimensione del file (operazione fattibile soltanto a runtime), perchè è un operatore del linguaggio che viene risolto a compile time (non è una funzione).<br />
Per sapere la dimensione di un file in bytes bisogna usare la funzione stat(), che restituisce tra le altre cose anche questa informazione.</p>
<p>Per file di dimensione arbitrariamente grande, la soluzione consiste nel leggere il file a &#8220;chunk&#8221; di grandezza fissata (ad esempio 1K alla volta), attraverso la funzione fread(), e inviare via socket questi chunk.<br />
Sia la trasmissione che la ricezione dovranno avvenire dentro un ciclo while, usando una variabile che conteggia i byte trasmessi/ricevuti, e ad ogni ciclo si dovrà effettuare una nuova fread/fwrite per leggere/scrivere quel chunk sul file.<br />
E&#8217; un&#8217;operazione che comunque comporta tutta una serie di problemi dovuti alla scarsa affidabilità del mezzo di trasmissione, pertanto è meglio affidarsi a protocolli già sperimentati come <acronym title="File Transfer Protocol">FTP</acronym>, che consentono anche il reinvio di chunk perduti, e il riordino degli stessi in caso di arrivo &#8220;in ordine sparso&#8221;, evento che si verifica frequentemente  su grandi reti come internet.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Alessandro Iezzi</title>
		<link>http://www.oscene.net/it/programmazione/c/come-programmare-le-socket-in-ambienti-gnulinux/comment-page-1#comment-600</link>
		<dc:creator>Alessandro Iezzi</dc:creator>
		<pubDate>Sun, 08 Aug 2010 02:23:57 +0000</pubDate>
		<guid isPermaLink="false">http://www.oscene.net/it/?p=275#comment-600</guid>
		<description>@Pietro:
Tenendo conto che non ho mai provato ad inviare file tramite delle socket, posso solo dire che se vuoi inviare dati più grandi devi obbligatoriamente modificare il buffer.
Una soluzione sarebbe quella di andare a creare un buffer dinamico che venga dimensionato in base al file da inviare. Per fare questo ci sono due modi:
1° Usando il C89 con la funzione &quot;malloc&quot;;
2° Usando il C99 con le VLA.
Penso anche che tramite l&#039;uso di sizeof ti potresti ricavare la dimensione in byte del file e di conseguenza adattare il buffer. La tipologia del socket dovrebbe essere invariata, ovvero usare SOCK_STREAM.
Magari se ho tempo qualche piccolo esperimento lo faccio questi giorni e se ne esce qualcosa di buono non esito a scrivere un articolo.

@marco:
Scusa se rispondo solo ora, ma l&#039;università ha preso il sopravvento sul mio tempo libero.
Mi dispiace doverti rispondere per commento, se non ti è chiaro qualcosa non esitare ad inviarmi una email.

La struttura hostent ha le seguenti variabili:
&lt;b&gt;
struct hostent
{
char *h_name;                 // Official name of host.
char **h_aliases;             // Alias list.
int h_addrtype;                // Host address type.
int h_length;                    // Length of address.
char **h_addr_list;          // List of addresses from name server.
#define h_addr  h_addr_list[0]  // Address, for backward compatibility.
};
&lt;/b&gt;
Come puoi ben notare, h_addr è il primo indirizzo del vettore di &quot;stringhe&quot; (intese come array di caratteri), ogni array è formato da 4 elementi, quindi 4 byte.
L&#039;indirizzo perciò viene memorizzato in questo modo:

&lt;b&gt;127.0.0.1 ---&gt; h_addr[0] = 127, h_addr[1] = 0, h_addr[2] = 0, h_addr[3] = 1&lt;/b&gt;.

Il casting, non fa altro che prendere questo piccolo vettore e trasformarlo in un intero formato da 4 byte. Esso è contenuto nella struttura in_addr:
&lt;b&gt;
struct in_addr {
uint32_t s_addr; // that&#039;s a 32-bit int (4 bytes)
};
&lt;/b&gt;
Viene quasi spontaneo ora eseguire:

&lt;b&gt;server_addr.sin_addr.s_addr = ((struct in_addr*)(hp-&gt;h_addr)) -&gt; s_addr;&lt;/b&gt;

Dovrebbe funzionare anche così:

&lt;b&gt;server_addr.sin_addr = (struct in_addr*)(hp-&gt;h_addr);&lt;/b&gt;

Spero sia esaustiva come risposta e grazie per il commento.</description>
		<content:encoded><![CDATA[<p>@Pietro:<br />
Tenendo conto che non ho mai provato ad inviare file tramite delle socket, posso solo dire che se vuoi inviare dati più grandi devi obbligatoriamente modificare il buffer.<br />
Una soluzione sarebbe quella di andare a creare un buffer dinamico che venga dimensionato in base al file da inviare. Per fare questo ci sono due modi:<br />
1° Usando il C89 con la funzione &#8220;malloc&#8221;;<br />
2° Usando il C99 con le VLA.<br />
Penso anche che tramite l&#8217;uso di sizeof ti potresti ricavare la dimensione in byte del file e di conseguenza adattare il buffer. La tipologia del socket dovrebbe essere invariata, ovvero usare SOCK_STREAM.<br />
Magari se ho tempo qualche piccolo esperimento lo faccio questi giorni e se ne esce qualcosa di buono non esito a scrivere un articolo.</p>
<p>@marco:<br />
Scusa se rispondo solo ora, ma l&#8217;università ha preso il sopravvento sul mio tempo libero.<br />
Mi dispiace doverti rispondere per commento, se non ti è chiaro qualcosa non esitare ad inviarmi una email.</p>
<p>La struttura hostent ha le seguenti variabili:<br />
<b><br />
struct hostent<br />
{<br />
char *h_name;                 // Official name of host.<br />
char **h_aliases;             // Alias list.<br />
int h_addrtype;                // Host address type.<br />
int h_length;                    // Length of address.<br />
char **h_addr_list;          // List of addresses from name server.<br />
#define h_addr  h_addr_list[0]  // Address, for backward compatibility.<br />
};<br />
</b><br />
Come puoi ben notare, h_addr è il primo indirizzo del vettore di &#8220;stringhe&#8221; (intese come array di caratteri), ogni array è formato da 4 elementi, quindi 4 byte.<br />
L&#8217;indirizzo perciò viene memorizzato in questo modo:</p>
<p><b>127.0.0.1 &#8212;&gt; h_addr[0] = 127, h_addr[1] = 0, h_addr[2] = 0, h_addr[3] = 1</b>.</p>
<p>Il casting, non fa altro che prendere questo piccolo vettore e trasformarlo in un intero formato da 4 byte. Esso è contenuto nella struttura in_addr:<br />
<b><br />
struct in_addr {<br />
uint32_t s_addr; // that&#8217;s a 32-bit int (4 bytes)<br />
};<br />
</b><br />
Viene quasi spontaneo ora eseguire:</p>
<p><b>server_addr.sin_addr.s_addr = ((struct in_addr*)(hp-&gt;h_addr)) -&gt; s_addr;</b></p>
<p>Dovrebbe funzionare anche così:</p>
<p><b>server_addr.sin_addr = (struct in_addr*)(hp-&gt;h_addr);</b></p>
<p>Spero sia esaustiva come risposta e grazie per il commento.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Pietro</title>
		<link>http://www.oscene.net/it/programmazione/c/come-programmare-le-socket-in-ambienti-gnulinux/comment-page-1#comment-599</link>
		<dc:creator>Pietro</dc:creator>
		<pubDate>Sat, 07 Aug 2010 19:37:38 +0000</pubDate>
		<guid isPermaLink="false">http://www.oscene.net/it/?p=275#comment-599</guid>
		<description>Ciao, come cambia il codice in caso di invio di un file (per esempio un pdf) di dimensione molto più grande del buffer?</description>
		<content:encoded><![CDATA[<p>Ciao, come cambia il codice in caso di invio di un file (per esempio un pdf) di dimensione molto più grande del buffer?</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: marco</title>
		<link>http://www.oscene.net/it/programmazione/c/come-programmare-le-socket-in-ambienti-gnulinux/comment-page-1#comment-584</link>
		<dc:creator>marco</dc:creator>
		<pubDate>Thu, 06 May 2010 13:02:28 +0000</pubDate>
		<guid isPermaLink="false">http://www.oscene.net/it/?p=275#comment-584</guid>
		<description>@Antonio Barba: Buono a sapersi ;)
Grazie ancora!</description>
		<content:encoded><![CDATA[<p>@Antonio Barba: Buono a sapersi <img src='http://www.oscene.net/it/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /><br />
Grazie ancora!</p>
]]></content:encoded>
	</item>
</channel>
</rss>

