[OT] Socket BSD su TCP in C
Scusate l'OT, ma ho provato su alcuni forum di programmazione C, poi ho
provato a guardare i sorgenti di un paio di server ftp e alla fine sono
alla frutta.
Devo modificare un programma C in modo che si metta in ascolto su una
qualsiasi porta TCP libera (> 1023) e comunichi al client (già connesso su
un'altra porta nota), qual è la nuova porta aperta. Discorso identico alla
modalità passiva dell'ftp.
Il codice dei server FTP che ho visto "risolve" il problema tentando la
chiamata a bind()+listen() su porte scelte a caso dall'applicazione. A me
sembra veramente una soluzione idiota. Va bene che funziona, ma cosa ci sta
a fare il sistema operativo?
Alcuni post raccolti qua e là mi hanno fatto sapere che impostando a zero il
valore di sin_port nella struttura sockaddr_in prima di chiamare la bind(),
ottengo che il sistema scelga una porta per me. Molto bene. Ma poi come
faccio a sapere quale porta ha scelto? Ho provato a fare il programmino di
esempio, sperando che mi impostasse il valore scelto al posto dello 0, ma
nulla, rimane a 0 (notare che il programmino qui sotto è una versione
ridotta in cui ho tolto quasi tutti i controlli di condizioni d'errore per
brevità, ma nella versione full gli errori non si verificano comunque):
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
int main(int argc, char *argv[])
{
int r;
struct addrinfo hints, *ai, *aitop;
memset(&hints, 0, sizeof(hints));
hints.ai_family = PF_INET;
hints.ai_socktype = SOCK_STREAM;
r = getaddrinfo("localhost", "0", &hints, &aitop);
for (ai = aitop; ai; ai = ai->ai_next)
{
int sock;
sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
if (sock < 0) /* ipv6 non supportato */
continue;
((struct sockaddr_in *)(ai->ai_addr))->sin_port = htons(0);
bind(sock, ai->ai_addr, ai->ai_addrlen);
listen(sock, 5);
printf("Ascolto sulla porta %d\n", (int)((struct sockaddr_in *
(ai->ai_addr))->sin_port);
}
return EXIT_SUCCESS;
}
Qual'è l'output?
Ascolto sulla porta 0
Sarà perché il networking l'ho imparato prima in Java, ma mi aspetto che una
cosa del genere sia possibile senza mettersi a fare cicli tentando la
fortuna...
Reply to: