Domanda

un clone di inetd in cui devo eseguire un server che stampa la IP e la porta del client connesso ad esso.

Come ho STDIN sovrascrittura e STDOUT con il descrittore di socket, mia soluzione iniziale per fare questo è stato quello di recuperare la struttura sockaddr_in, che contiene le informazioni necessarie. Facendo questo con getsockname(), tuttavia, sta tornando una struttura vuota, con tutti i bit impostati a 0.

Qualche idea di ciò che è sbagliato con il mio approccio? Ci sono altri approcci che posso usare per recuperare l'IP / porta?

Grazie

È stato utile?

Soluzione

R .. ha sottolineato, è necessario utilizzare getpeername . Sia che la funzione e getsockname prendono un descrittore di file come primo argomento, non un torrente puntatore (FILE *). Utilizzare fileno(stdin) per ottenere il descrittore di file per l'input standard (o hard-code a STDIN_FILENO, in quanto la costante).

Inoltre, l'ultimo argomento per getsockname e getpeername dovrebbe essere un puntatore a socklen_t, non è una costante, e si dovrebbe utilizzare un sockaddr_in per TCP / IP:

struct sockaddr_in peeraddr;
socklen_t peeraddrlen = sizeof(peeraddr);
getpeername(STDIN_FILENO, &peeraddr, &peeraddrlen);

Vedere un esempio completo qui .

Altri suggerimenti

Usa getpeername. Ho il sospetto che il tuo problema è che sta tornando getsockname le informazioni per il proprio lato (locale) della presa, che è probabilmente destinata a 0.0.0.0 (che significa che può accettare connessioni da qualsiasi interfaccia).

Modifica Credo di aver trovato il bug attuale lettura del codice. Questa linea è sbagliato:

getsockname(stdin, &addr, sizeof(addr));
funzioni

??Il getsockname e getpeername prendere un socklen_t * ( puntatore ) come terzo argomento, non un size_t. Il compilatore dovrebbe essere dicendo su questo errore a meno che non si è dimenticato di includere un colpo di testa con il prototipo getsockname. Inoltre, come si è già detto, stdin non è corretto. Prova:

socklen_t len = sizeof addr;
getpeername(0, &addr, &len);

o (solo C99):

getpeername(0, &addr, (socklen_t[1]){sizeof addr});

Si dovrebbe anche essere il controllo del valore di ritorno; Se così fosse, si vedrebbe che è il ritorno errori.

Se avete bisogno di quelle informazioni per il client remoto, è necessario chiamare getpeername () .

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top