PDA

View Full Version : [C] Struct IP


SandroDe
20-10-2009, 17:41
Se dovessi memorizzare un IP e non volessi utilizzare una struct stringa, come potrei fare?

Ikon O'Cluster
20-10-2009, 18:00
Dipende... cosa ci devi fare?

Potresti usare un array di 4 unsigned char (per IPv4), se hai bisogno dei singoli gruppi nella notazione decimale puntata. Non dimenticare poi che un indirizzo IPv4 in realtà altro non è che un numero a 32 bit. Quindi ti basta un qualsiasi unsigned purchè sia tale che sizeof(questo_unsigned) >= 4.

SandroDe
20-10-2009, 18:32
Mi serve perchè devo legare l'ip alla socket lato server.
Quindi non so se una struct di tipo string , passata come argomento ad una inet_addr vada bene; visto che io ho visto una inet_addr ricevere un indirizzo IP
:)

Ikon O'Cluster
20-10-2009, 18:59
Ah ok... allora usi i socket BSD. Estraggo dai miei appunti di qualche anno fà:

- Esempio di inizializzazione delle struttura dati per gli indirizzi


char* ip_address[256] = “192.168.1.1”;
unsigned short int tcp_port_number = “1234”;
struct sockaddr_in endpoint;

bzero(&endpoint, sizeof(endpoint));
endpoint.sin_family = AF_INET;
endpoint.sin_port = htons(tcp_port_number);
----------------------------------------------------------------------
/* Indicazione di un indirizzo specifico (192.168.1.1): */
endpoint.sin_addr.s_addr = inet_addr(ip_address);
----------------------------------------------------------------------
/* Alternativa: */
inet_pton(AF_INET, ip_address, &endpoint.sin_addr);
----------------------------------------------------------------------
/* Per indicare un indirizzo generico: */
endpoint.sin_addr.s_addr = INADDR_ANY;


- Esempio di creazione di socket TCP (se hai bisogno di UDP ho anche quello e anche per il multicast ho qualcosa)


int client(const char* ip_addr, int tcp_port) {
int ret;

int sv_sd = socket(PF_INET, SOCK_STREAM, 0);
if(sv_sd < 0) return -1;

struct sockaddr_in sv_addr;
bzero(&sv_addr, sizeof(sv_addr));

sv_addr.sin_family = AF_INET;
sv_addr.sin_port = htons(tcp_port);
sv_addr.sin_addr.s_addr = inet_addr(ip_addr);

ret = connect(sv_sd, (struct sockaddr*)&sv_addr, sizeof(sv_addr));
if(ret < 0) return -1;

return sv_sd;
}

int server(unsigned short int tcp_port, int queue_len, int non_blocking, int reuse) {
int ret;
int sv_sd = socket(PF_INET, SOCK_STREAM, 0);

if(sv_sd < 0) return -1;

struct sockaddr_in sv_addr;
bzero(&sv_addr, sizeof(sv_addr));

sv_addr.sin_family = AF_INET;
sv_addr.sin_port = htons(tcp_port);
sv_addr.sin_addr.s_addr = INADDR_ANY;

ret = bind(sv_sd, (struct sockaddr*)&sv_addr, sizeof(sv_addr));
if(ret < 0) return -1;

ret = listen(sv_sd, queue_len);
if(ret < 0) return -1;

int val;

if(non_blocking) {
val = fcntl(sv_sd, F_GETFL, NULL);
fcntl(sv_sd, F_SETFL, value | O_NONBLOCK);
val = 1;
}

if(reuse) {
#ifdef SO_REUSEADDR
setsockopt(sv_sd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
#endif

#ifdef SO_REUSEPORT
setsockopt(sv_sd, SOL_SOCKET, SO_REUSEPORT, &val, sizeof(val));
#endif
}

int cl_sd;
struct sockaddr_in cl_addr;
int cl_addr_len = sizeof(cl_addr);
cl_sd = accept(sv_sd, (struct sockaddr*)&cl_addr, &cl_addr_len);
return cl_sd;
}


// ESEMPIO D'USO: Sul server 192.168.1.1...
#define BUF_LEN 128

int len;
char recv_buf[BUF_LEN];
char send_buf[BUF_LEN];

int sd = server(12345, 10, 0, 0);
if(sd < 0) return -1;
//...

len = recv(sd, recv_buf, BUF_LEN, 0);
if(len < 0) return -1;
//...

len = send(sd, send_buf, BUF_LEN, 0);
if(len < 0) return -1;
//...



// ESEMPIO D'USO: Sul client...
#define BUF_LEN 128

int len;
char recv_buf [BUF_LEN];
char send_buf [BUF_LEN];

int sd = client("192.168.1.1", 12345);
if(sd < 0) return -1;
//...

len = send(sd, send_buf, BUF_LEN, 0);
if(len < 0) return -1;
//...

len = recv(sd, recv_buf, BUF_LEN, 0);
if(len < 0) return -1;
//...


Non sapendo di preciso cosa volevi ho copiato tutto :) prendi solo quello che ti serve :) Il codice non mi pare di averlo testato, ma concettualmente dovrebbe essere OK.