2010-08-25 2 views
1

Comment trouver l'adresse IP de l'expéditeur d'un paquet udp qui a été reçu sur un périphérique exécutant iOS 3.2 ou supérieur?Comment identifier l'adresse IP de l'expéditeur d'un paquet udp reçu sur un appareil iOS?

Par exemple, si vous utilisez Python sur un ordinateur, j'utiliser SocketServer.UDPServer qui prend une sous-classe de SocketServer.BaseRequestHandler qui définit le rappel handle. Lorsqu'un paquet arrive, le rappel est appelé et l'adresse IP de l'expéditeur est self.client_address, où self est l'instance SocketServer.BaseRequestHandler.

Malheureusement, je ne sais pas comment extraire ces informations ou accéder à l'en-tête IP associé lors de la programmation en Objective C et en utilisant les frameworks fournis pour iOS. À l'heure actuelle, la seule solution que j'ai est d'écrire explicitement l'adresse IP de l'expéditeur sur le corps du paquet udp, mais je préfère ne pas compter sur l'expéditeur de mettre cette information là si je n'ai pas à le faire.

Répondre

3

Vous n'avez pas mentionné l'API que vous utilisez pour recevoir le paquet. N'écrivez pas l'adresse IP dans le paquet lui-même car le paquet peut passer par un certain nombre de traductions d'adresses réseau avant qu'il ne vous parvienne.

Vous pouvez utiliser des sockets BSD standard pour réaliser cette tâche. Il y a aussi quelques classes de Foundation qui s'enroulent autour des sockets BSD, mais je ne les ai pas utilisées personnellement, donc je ne peux pas vous donner un exemple décent.

// for IPv4 (IPv6 is a little different) 

ssize_t received; 
char buffer[0x10000]; 
struct sockaddr_in listenAddr; 
struct sockaddr_in fromAddr; 
socklen_t fromAddrLen = sizeof fromAddr; 

listenAddr.sin_family = AF_INET; 
listenAddr.sin_port = htons(12345); // change to whatever port 
listenAddr.sin_addr.s_addr = htonl(INADDR_ANY); 

int s = socket(AF_INET, SOCK_DGRAM, 0); // create UDP socket 
if (s == -1) 
    exit(1); // failed to create socket 

if (bind(s, (struct sockaddr *) &listenAddr, sizeof listenAddr)) 
    exit(2); // failed to bind to port 12345 for any address 

received = recvfrom(s, buffer, sizeof buffer, 0, (struct sockaddr *)&fromAddr, &fromAddrLen); 
if (received == -1) 
    exit(3); // some failure trying to receive data 

// check the contents of buffer, the address of the source will be in 
// fromAddr.sin_addr.s_addr but only if (fromAddrLen == sizeof fromAddr) 
// after the call to recvfrom. 

char display[16] = {0}; 
inet_ntop(AF_INET, &fromAddr.sin_addr.s_addr, display, sizeof display); 

NSLog (@"The source is %s.", display); 
// could show "The source is 201.19.91.102." 
+0

Remarque le paramètre fromAddr de recvfrom - c'est la partie intéressante. Il est rempli avec l'adresse/le port de l'expéditeur. –

Questions connexes