PDA

Visualizza la versione completa : [C]unix system call , connect()


pistilloi
12-12-2012, 01:28
Vorrei connettermi ad'un indirizzo IP e leggere un'intero senza segno(host byte order) in una porta nota.


#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>

#define DEST_IP "141.138.199.118"
#define DEST_PORT 5842

int main(void)
{
int sockfd;
struct sockaddr_in my_addr;
struct sockaddr_in dest_addr;

sockfd = socket(PF_INET, SOCK_DGRAM, 0);

my_addr.sin_family = AF_INET;
my_addr.sin_port = 0; // sceglie una porta a caso non in uso
my_addr.sin_addr.s_addr = INADDR_ANY; // usa il mio indirizzo IP
memset(my_addr.sin_zero, '\0', sizeof my_addr.sin_zero);

dest_addr.sin_family = AF_INET; // host byte order
dest_addr.sin_port = DEST_PORT; // long, network byte order
dest_addr.sin_addr.s_addr = inet_addr(DEST_IP);
memset(dest_addr.sin_zero, '\0', sizeof dest_addr.sin_zero);

connect(sockfd, (struct sockaddr *)&dest_addr, sizeof dest_addr );

unsigned int buffer[4];

recvfrom( sockfd, buffer, 4, 0,
(struct sockaddr *)&my_addr,
(int *) sizeof(struct sockaddr) ); //si ferma qua

int register i;
for(i=0 ; i<4 ; i++)
printf("%d° intero letto: %d",i , buffer[i]);
printf("\n");

return 0;
}

Il mio programma non va più avanti dopo l'invocazione di recvfrom(), ho pensato che rimane in attesa poiché la porta a cui sono connesso non invia nulla, ma di ciò non sono molto convinto. Quindi la mia domanda è, la funzione resta in attesa perché non riceve niente? Se no, perché non va avanti?

oregon
12-12-2012, 02:45
Devi scrivere



dest_addr.sin_port = htons(DEST_PORT);


e poi



unsigned int buffer[4];
int my_addr_size = sizeof (my_addr);
recvfrom(sockfd, (char *)buffer, 16, 0, (struct sockaddr *)&my_addr, &my_addr_size);


se devi ricevere 4 interi (16 byte). Ma se devi ricevere 4 byte allora



unsigned char buffer[4];
int my_addr_size = sizeof (my_addr);
recvfrom(sockfd, (char *)buffer, 4, 0, (struct sockaddr *)&my_addr, &my_addr_size);

pistilloi
12-12-2012, 12:16
Ma nella chiamata recvfrom(), devo passarli il mio sockaddr o quello da cui devo leggere?

oregon
12-12-2012, 13:42
Vedi

http://pubs.opengroup.org/onlinepubs/009695399/functions/recvfrom.html

c0der
12-12-2012, 13:48
@pistilloi Sai che stai usando l'UDP e non il TCP vero? Non vorrei che ti fossi sbagliato su questo...

pistilloi
12-12-2012, 14:07
A null pointer, or points to a sockaddr structure in which the sending address is to be stored. The length and format of the address depend on the address family of the socket.

La descrizione del parametro in questione, dice di passare a recvfrom() una struct sockadder contenente l'indirizzo di invio. Ma si riferisce alla macchina da cui devo leggere che mi deve inviare i byte, per cui devo mettere il mio sockadder?

@c0der
Non so molto della macchina in cui devo leggere, purtuttavia impostando la comunicazione in SOCK_STREAM, l'esecuzione si impantanava in connect(), per cui o provato in altre modalità e con SOCK_DGRAM si connette.

c0der
12-12-2012, 14:12
Originariamente inviato da pistilloi
@c0der
Non so molto della macchina in cui devo leggere, purtuttavia impostando la comunicazione in SOCK_STREAM, l'esecuzione si impantanava in connect(), per cui o provato in altre modalità e con SOCK_DGRAM si connette.

Vorrei farti notare che con i socket UDP la connect praticamente non fa nulla:
http://users.lilik.it/~mirko/gapil/gapilsu270.html

Ciao.

P.S. Prova innanzitutto a connetterti con un client che siamo tranquilli che funziona, cioè il classico telnet.

pistilloi
12-12-2012, 14:24
Grazie, quindi se eseguo connect() su un socket in SOCK_DGRAM posso usare direttamente read() e write(), comunque non penso che recfrom() non funzioni più a questo punto. Provo a non chiamare connect e vedo che succede...

c0der
12-12-2012, 15:35
Originariamente inviato da pistilloi
Grazie, quindi se eseguo connect() su un socket in SOCK_DGRAM posso usare direttamente read() e write(), comunque non penso che recfrom() non funzioni più a questo punto. Provo a non chiamare connect e vedo che succede...

A parte il discorso della connect, al 99% a te serve il tcp non l'udp, per questo ti suggerivo di usare il telnet.
Conosci la differenza tra udp e tcp? È fondamentale.

EDIT:
Googlando ip/porta nel tuo esempio salta fuori questo: http://www.overthewire.org/wargames/semtex/
Non è proprio il massimo chiedere su un forum domande del genere se vuoi inoltrarti in questi giochi.
Dovresti conoscere l'argomento rete a menadito a priori.

pistilloi
12-12-2012, 18:50
Ho letto la teoria prima di cercar di scrivere la soluzione, so bene quali sono le differenze tra i protocolli citati; anche io volevo approcciare la soluzione in tcp, ma cosi facendo non si connetteva... Comunque non ho certo chiesto la soluzione del livello, il mio problema e ben più specifico. Oltretutto quel gioco mi pare un'ottimo modo per imparare.

Comunque: http://users.lilik.it/~mirko/gapil/gapilsu266.html


Se non sono disponibili dati la funzione si blocca, a meno di non aver aperto il socket in modalità non bloccante, nel qual caso si avrà il solito errore di EAGAIN. Qualora len ecceda la dimensione del pacchetto la funzione legge comunque i dati disponibili, ed il suo valore di ritorno è comunque il numero di byte letti.

Loading