Connaitre son adresse IP en cocoa
ettibo
Membre
Bonjour à tous,
je voulais savoir s'il y avait un moyen de connaitre facilement son adresse IP en cocoa?
Je voudrais faire un système où mon ipad soit connecté en wifi, regarde son ip au lancement de l'application, puis écoute sur l'adresse de broadcast, à ce moment là , le serveur va envoyer son ip sur l'adresse de broadcast. C'est alors que l'ipad va récupéré cette adresse ipV4 sur 4 octets pour se connecter dessus.
Merci d'avance.
je voulais savoir s'il y avait un moyen de connaitre facilement son adresse IP en cocoa?
Je voudrais faire un système où mon ipad soit connecté en wifi, regarde son ip au lancement de l'application, puis écoute sur l'adresse de broadcast, à ce moment là , le serveur va envoyer son ip sur l'adresse de broadcast. C'est alors que l'ipad va récupéré cette adresse ipV4 sur 4 octets pour se connecter dessus.
Merci d'avance.
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
Et pourquoi ne pas utiliser Bonjour/ZeroConf, cela ne répondrait-il pas à ta question ?
NSNetService Programming Guide
BonjourWeb : Un Sample Code d'Apple
Et sinon en faisant une petite recherche rapide on trouve plein de samples. Objective-C étant du C, toutes les réponses retournées par Google permettant de faire ça en C sont donc acceptables, comme celle-ci (pas testée donc à valider)
Voilà pour les pistes !
Et il y a déjà tout ce qu'il faut dans l'API iOS pour utiliser Bonjour (autant en tant que serveur qu'en tant que client).
Quand tu es connecté sur un réseau, ton device a une ip, et je voulais la connaitre pour ensuite accéder à mon adresse de broadcast.
Je vais regarder du coté de Bonjour et ZeroConf alors.
Merci
Une ou plusieurs IP par interface réseau (l'iPad Wifi en a au moins 3 je pense, en0, bt0 et lo0 sans doute), dont dans la boucle une IP locale donc.
Bon après je suppose que tu veux l'IP LAN sur l'interface réseau correspondant au Wifi, et pas l'IP WAN (et encore moins la loopback), mais je posais la question car juste "l'adresse IP" ça peut ne pas suffir pour décrire quelle IP tu veux (et ça dépend de la topologie de ton réseau aussi, bien que là encore j'imagine que tu as un réseau domestique assez classique avec une Box qui génère le réseau Wifi, et pas un VLAN ou une borne Wifi qui fait Bridge, mais comme je sais pas c'est aussi une question à se poser)
Il est très important de faire ces deux includes
#include <ifaddrs.h>
#include <arpa/inet.h>
Ceci dit le début du code est bien, mais la fin c'est plutôt foireux (à la fois pas clean mais loin d'être exact en plus) :
Sinon pour tous les sous-réseaux qui ne seront pas de classe C (type /24) ton code en plus d'être lourd de conversions et d'une approche étrange, ne va pas marcher et ne pas te retourner la bonne valeur du tout...
Ouais, mais au moins c'est standard puisqu'utilisé par tout un tas de périphériques réseau, comme les imprimantes.
Si tu as une solution plus propre que celle que j'ai faite, je suis tout à fait preneur.
Merci
Typiquement :
- une méthode qui retourne l'IP de l'iPad en retour, et pas sous forme de NSString mais sous forme d'une structure du genre sockaddr_in ou équivalent, ou éventuellement un NSData les encapsulant, enfin bref les 4 octets de l'IP et pas leur représentation décimale en NSString qui n'est qu'une représentation (tu mélanges Vue et Modèle là ), et tant qu'on y est le masque de sous-réseau qui doit pas être très loin à récupérer si on a l'IP, genre dans le ifa_addr ou pas loin
- une méthode qui à partir de l'IP (sous forme de 4 octets toujours, aucune raison de passer en NSString et faire des conversions à ce stade) et du masque de sous-réseau (idem) calcule l'adresse de broadcast (facile avec des bitwise masks, genre [tt]long broadcastAddr = (long)ip | ~(long)mask[/tt] un truc dans le genre
- Et seulement à la toute fin, uniquement au moment où tu as besoin de représenter ton IP sous forme de chaà®ne avec les valeurs décimales des octets séparés par des points (façon "a.b.c.d" quoi), formatter cette IP avec ce format (faut pas mélanger les diverses parties du MVC !!)
Si tu es certain d'une adresse IP "Class C" (192.168.XXX.XXX) tu peux garder ta méthode pour trouver l'adresse de broadcast mais en général on ne sait pas quel matériel un utilisateur va utiliser et si tu creuses un peu les fonctions Posix (je crois que c'est du Posix) tu verras que c'est puissant, rapide et très efficace. Quoiqu'un peu rugueux
Pour voir à quoi ça ressemble tu ouvres la fenêtre de la documentation (dans l'Organizer pour Xcode 4) et tu cherches après la fonction que tu utilises "getifaddrs". ça donne, dans les références, la "Man page" de getifaddrs -- get interface addresses avec aussi des liens dans le texte qui permettent de creuser un peu le sujet sans aller sur Google et, dans Sample Code, un exemple que tu peux ouvrir dans Xcode pour étude via le debugger (en fait je n'ai pas regardé celui là précisément mais souvent on peut les faire tourner et en disséquer le fonctionnement pas à pas). Autre avantage de la démo: tu retrouves ce que dit Ali, notre maà®tre à tous sur la manière dont en POO les données de ta classe sont "encapsulées" et les calculs en interne séparés (c'est le modèle) et la manière d'y accéder proprement dans ton Controller.
Tout dépend de ce que tu espères faire avec ton application une fois qu'elle sera achevée et de ton envie d'apprendre des choses
PS: sans l'avoir fait tourner j'ai compilé le projet pour le débarrasser des erreurs et warnings dus au fait qu'il était destiné à d'anciennes versions de l'OS et te le mets en pièce jointe
suite à vos conseils, je me suis remis à penser en mode C, en effet, vous avez raison, ça me parait beaucoup plus propre avec cette méthode et en plus, j'ai une adresse de broadcast différente (par différente, j'entends qui s'adapte vraiment au masque de sous réseau).
Si ça intéresse des gens.
voilà , dites moi ce que vous en pensez
En dernier point pour faire un truc propre je manipulerais les adresses IP avec une classe ou structure dédiée.
Par exemple, c'est vrai que les structures genre sin_addr utilisées par les librairies C bas niveau sont parfois un peu déroutante, mais par contre tu peux toujours prévoir une classe IPAddress par exemple pour manipuler des adresses IP et les passer d'une méthode à l'autre. Ou même plus simple si tu veux pas créer de classe, un simple [tt]typedef union { unsigned long bytes; unsigned char byte[4]; } ip_addr;[/tt] par exemple peut suffire, pour avoir un type qui permette de véhiculer 4 octets qui peuvent tout aussi bien être interprétés comme un gros entier long -- pratique pour faire le masque entre l'IP et le masque de sous réseau en une seule opération plutôt que d'avoir à découper octet par octet et faire une boucle for -- que comme 4 octets courts séparés (pratique pour la représenter en une chaine "a.b.c.d" au dernier moment.
Du coup tu adaptes ton code pour que [tt]getWifiIpAddress[/tt] et [tt]netmaskForWifiInterface[/tt] retournent chacun une structure ip_addr (ou la classe IPAddress si tu as préféré créer une classe) et non plus une NSString (et surtout sans passer par une conversion sin_addr->cstring->NSString->ip_addr, autant directement construire ton ip_addr à partir de sin_addr)
Et ensuite le code de pourra tout simplement être : Même plus besoin de tout ton code de boucles for et de redécoupage des NSString et réinterprétation en intValue dans ton [tt]broadcastAddressForAddress:withMask:[/tt] !
Bon en pratique plutôt que de faire ça, tu peux aussi donc créer plutôt une classe IPAddress si tu préfères plutôt que ce typedef d'union que j'ai fait, ou sinon plutôt que de t'embêter le plus simple reste d'utiliser ce qui existe déjà , à savoir la structure "sin_addr" qui représente déjà les octets d'une adresse IP, donc pourquoi réinventer la roue...