Envoie d'image ou de vidéo et connexion à  un serveur

miketyzmiketyz Membre
02:03 modifié dans API AppKit #1

Mon premier post ici ça se fête  :p
Moi aussi je complimente les gens qui ont eu la bonne idée de créer ce site qui avec le projet omega sont les meilleurs ressources françaises en ce qui concernent l'objective c et cocoa.

Bref, j'ai un petit projet personnel : créer un moyen de remplir mon site internet grace a une interface toute jolie sur mon mac. Le serveur est entrain d'être écrit en C++ et le client donc en ObjC/Cocoa.

Je suis entrain de regarder comment faire communiquer mes 2 programmes. Comme c'est ma première du genre je préfère poser la question avant d'approfondir.
Est-ce que le NSNetService peut me permettre de réaliser ce que je souhaite ? (Connexion au serveur C++, échange de données) ?
Je vais nécessiter l'envoi de photo ou vidéo donc comment peut-on faire cela (une fois connecté ;) ) ?

Merci d'avance.

Réponses

  • miketyzmiketyz Membre
    02:03 modifié #2
    Bon je la fait version blog puisque ça n'inspire personne ;)

    Mercredi 3 Janvier

    Je supposais qu'il fallait utiliser CFNetwork qui me semblais être la seul manière (sans ajout de framework) de travailler avec les sockets aux niveaux les plus bas.

    Reste à  savoir s'il était, avec cet outil, possible d'envoyer mes images ou vidéos...
  • 02:03 modifié #3
    NSNetService = rendez-vous/bonjour: ça permet juste de repérer des services sur un réseau, mais ça ne fait rien niveau "communication". Niveau communication: deux possibilités: les classiques sockets en C, ou en objective-c, les objets distribués (NSConnection, NSProxy & autres trucs dans le genre). Si maintenant tu veux remplir un serveur avec des fichiers, le plus simple est de passer par des services standards tels que (s)FTP ou autres WebDav. Tu trouveras un framework tout fait pour ça ici : http://opensource.utr-software.com/connection/
  • miketyzmiketyz Membre
    janvier 2007 modifié #4
    Merci de ta réponse.

    Quand tu parle de socket en objective C tu parles de CFSocket ?

    Je peux pas utiliser les objets distribués à  travers le net, si ? et je peux pas demander à  mon serveur C++ de répondre à  cette méthode ?

    Si je veux pas utiliser de framework, je suppose que je peux envoyer mes données via la socket non ?
    Et si je veux utiliser ton framework, qu'est ce qu'il faut que je fasse au niveau du serveur ? Est-ce que c'est mon programme en C++ qui va l'intercepter ou est-ce qu'apache va s'en occuper ?

    Je précise que j'ai des contraintes scolaires :) Je dois faire le serveur en C++ et le client en objc...  :crackboom:-
  • 02:03 modifié #5
    Avec le framework: apache s'en occupe si tu as activé le module WebDAV, sinon ce framework est aussi capable de se connecter à  un serveur ftp classique. Bref à  toi de voir, mais dans tous les cas, ce ne sont que des classiques du Web.

    Sans le framework: tu peux les envoyer via un socket, mais là  je ne m'y connais pas.
  • BruBru Membre
    02:03 modifié #6
    Pour le client en ObjC, la classe NSSocketPort est suffisante je pense (cette classe est un wrapper pour les sockets BSD).
    Après création du socket, il suffit de le lier à  un NSFileHandle pour gérer la communication (via les méthodes readXXX et writeData).

    <br />NSSocketPort *s;<br />NSFileHandle *fh;<br /><br />s=[[NSSocketPort alloc] initRemoteWithTCPPort:9876 host:@&quot;ton_serveur.com&quot;]<br />fh=[[NSFileHandle alloc] initWithFileDescriptor:[s socket]];<br />
    


    Bref, si t'as déjà  joué avec les sockets BSD, tu n'auras pas de difficulté en ObjC.

    .
  • miketyzmiketyz Membre
    02:03 modifié #7

    Je suis honoré de voir que toute la haute de ce forum s'interresse à  mes problèmes de débutant ; je vous en remercie o:)

    Je mets ce lien pour ce que ça interresse, c'est une comparaison de framework réseau :
    http://www.stepwise.com/Articles/Technical/2003-04-22.01.html
    Perso, j'ai essayé SmallSocket ça c'est connecté en 3 lignes de code et ça s'implifie la syntaxe  :o

    Je vais quand même essayé de me creuser la tête un peu plus et essayer la méthode Bru : ça me laissera un peu plus libre de mes choix après et ça serait mettre utile pour l'envoie de fichier multimédia. Si j'y arrive je passe la méthode ;)
  • miketyzmiketyz Membre
    02:03 modifié #8

    Bru I need your :why?:

    Je comprends pas tout.
    Si j'utilise le code de Bru tel quel aucune connexion n'est crée. Pourtant dans la doc Apple c'est bien marqué que la connexion se crée lors de l'envoi de donnée donc j'ai ajouté un writeData mais le compilateur m'insulte (Bad File Descriptor). J'ai essayé :
    [fh writeData: [@&quot;YEAH&#092;n&quot; dataUsingEncoding:NSISOLatin1StringEncoding]];
    

    et :
    [[s socket] writeData: [@&quot;YEAH&#092;n&quot; dataUsingEncoding:NSISOLatin1StringEncoding]];
    


    Ensuite, j'ai essayé de rajouter un NSConnection par dessus ce code, et là  le serveur (en C++) détecte ma demande. Mais malheureusement pas moyen de lui envoyer de la donnée. J'en suis à  ça :

    <br />&nbsp; &nbsp;  id server;<br />	NSSocketPort *s;<br />	NSFileHandle *fh;<br />	NSConnection *connection;<br /><br />	s=[[NSSocketPort alloc] initRemoteWithTCPPort:2007 host:@&quot;localhost&quot;];<br />	fh=[[NSFileHandle alloc] initWithFileDescriptor:[s socket]];<br />	connection = [NSConnection connectionWithReceivePort:nil sendPort:s];<br />	server = [connection rootProxy];<br /><br />	[fh writeData: [@&quot;YEAH&#092;n&quot; dataUsingEncoding:NSISOLatin1StringEncoding]];<br />
    


    Est-ce que je me perds ou il me manque un petit truc ?

    Je rajoute une petite précision ça fait 3-4 jours que je me suis lancé (mais pas à  moitié) dans Cocoa/objc/Xcode et IB donc il y a encore quelques points noirs...
  • miketyzmiketyz Membre
    janvier 2007 modifié #9
    I got it.  <3 <br />
    Bon alors, finalement, le framework Smallsocket répond tout à  fait à  mes attentes...

    J'ai ouvert un avec un FileHandler mon fichier je lui recuper 256 char par 256 char et l'envoie a mon serveur. Et ça marche pour tous les fichiers.

    2 remarques quand même :
    - J'ai coupé le fichier par tranche de 256 octets parce qu'il n'est pas trop pour tout balancé d'un coup (Exception relevée : Broken pipe); donc while qui surveille la position du pointeur d'offset sur le file et c'est réglé (par contre j'ai pas trouvé la valeur limite du buffer / J'ai vu 1024 octets sur un autre site mais à  vérifier...);
    - A la reception coté serveur, il faut se méfier des caractères de fin de chaine... Au départ j'utilisais fputs en lui donnant mon buffer sauf que cette fonction s'arrête au premier '\0' qu'elle croise. Pour transférer un texte c'est pas très dérangeant mais pour le reste (image, exe, vidéo...) ça arrive souvent. Du coup il copie par exemple que 2 octets sur les 256 tranférés et on finit avec un fichier de 400Ko alors que l'original était de 600... Pour y remédier il suffit d'utiliser du caractère par caractère dans un for (fputc).

    Voila, suffisait de tester.

    Ceci dit, si quelqu'un pouvait éclairer ma lanterne concernant mon problème avec NSSocket ça m'interresse toujours même si je l'utiliserais pas pour ce projet ;)
  • BruBru Membre
    02:03 modifié #10
    En relisant la doc sur NSSocket, je viens de voir que la manipulation des NSScoket via NSFileHandle n'est possible qu'en local (serveur et client sur la même machine), ce qui explique ton erreur "Bad File Descriptor".

    Donc, NSSocket n'est pas utilisable dans ton contexte.
    Pour une solution pure cocoa (sans framework externe), il te reste NSStream. Mais l'emploi de cette classe est assez complexe.

    Concernant ton transfert, "broken pipe" évoque l'utilisation de pipes pour la communication.
    Or je me souviens que sous OSX, la taille d'un conduit est fixé à  512 octets.
    A tout hasard, consulte le fichier limits.h dans les developer tools pour voir si une telle taille est référencée.

    .
  • miketyzmiketyz Membre
    02:03 modifié #11

    En fait je pense que ça dépend des configs des 2 cotés...

    Il semblerait que le framework me limite le buffer de lecture à  4096 octets mais rien sur celui d'écriture (ou pas trouver  :)) :
    // SOCKET_DEFAULT_READ_BUFFER_SIZE is the default size of the buffer <br />// used by readData, which all the other read calls are built upon.&nbsp; <br />// readData will not read more than this amount in a single call.<br />// You can change this buffer size on a per-socket basis by<br />// calling -setReadBufferSize<br /><br />#define SOCKET_DEFAULT_READ_BUFFER_SIZE 4096
    


    Je suppose donc qu'en écriture c'est à  mon serveur C++ de choisir. Si jamais je dépasse la taille il quitte (un segfault surement) ce qui lève l'eception du côté client.
    Dès que j'ai 5 minutes j'irai regardé par curiosité les .h afin de trouver la valeur maximum réel. Cependant en faisant des tests j'ai pu monter jusqu'à  environ 10000 octets et à  20000 il plantait. Maintenant, j'utilise des valeurs plus basses, ça sera moins rapide (appellera recv 2 ou 3 fois plutôt qu'une) mais je pense pas qu'on sentira vraiment la différence... Là  je l'ai mis à  4096 des 2 côtés et ça fonctionne très bien.

    Et merci d'avoir utiliser de ton temps pour les NSSockets  :-*

    Si certains sont interressés par du code plus concret dites le moi j'en mettrais.
Connectez-vous ou Inscrivez-vous pour répondre.