2010-08-25 4 views
1

Как узнать IP-адрес отправителя пакета udp, который был получен на устройстве с iOS 3.2 или выше?Как идентифицировать ip-адрес отправителя пакета udp, полученного на устройстве iOS?

Например, если с помощью Python на компьютере, я бы использовал SocketServer.UDPServer, который принимает подкласс SocketServer.BaseRequestHandler который определяет handle обратного вызова. Когда приходит пакет, вызывается обратный вызов и ip-адрес отправителя находится в self.client_address, где self является экземпляром SocketServer.BaseRequestHandler.

К сожалению, я не знаю, как извлечь эту информацию или получить доступ к связанному заголовку ip при программировании в Objective C и с использованием фреймворков, предоставляемых для iOS.

Прямо сейчас единственное решение, которое у меня есть, - это явно написать ip-адрес отправителя в теле пакета udp, но я бы предпочел не полагаться на отправителя, помещая эту информацию там, если мне это не нужно.

ответ

3

Вы не указали, какой API вы используете для получения пакета. Не записывайте IP-адрес в сам пакет, потому что пакет может пройти через несколько сетевых адресов, прежде чем он попадет к вам.

Вы можете использовать обычные разъемы BSD для выполнения этой задачи. Есть также несколько классов Foundation, которые обертывают сокеты BSD, но я не использовал их лично, поэтому я не могу дать вам достойный пример.

// 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

Примечание: recvfrom's fromAddr parameter - это интересная деталь. Он заполняется адресом/портом отправителя. –

Смежные вопросы