Question

J'ai lu beaucoup de questions à ce sujet sur ce site Web, mais ils n'ont pas répondu tranquillement à ma question. Si vous ne pouvez pas être ### à propos de mon objectif ou de mon arrière-plan, passez à la question.

Mon objectif

Il s'agit de créer un serveur pouvant fonctionner sous Mac OS X 10.4+ et ultérieur, de le transférer sous Windows XP / Vista (vous ne savez pas encore comment procéder, mais c'est un problème pour plus tard).

Ensuite, laissez l’iPhone comme client capable de voir les noms d’ordinateur exécutant le serveur (via WiFi). L'utilisateur de l'iPhone peut ensuite sélectionner le nom de l'ordinateur pour se connecter au serveur sur cet ordinateur.

Après cela, ils peuvent s’envoyer des messages texte simples. Par exemple, l'iPhone envoie "Knock Knock" et le serveur répond "Qui est là?". Ou un simple client: "Ping", le serveur répond "Pong" fera l'affaire.

Arrière-plan

J'ai déjà utilisé des sockets par le passé, mais il était très facile de créer un serveur TCP / IP uniquement avec Visual Basic 6 avec WINSOCKET.dll.

server.host = localhost;
server.port = 12203;
server.listen(); 

Avec le client, il me suffisait de procéder comme suit pour me connecter.

client.connect(localhost, 12203);

Il y avait des rappels disponibles tels que connect, close, dataArrival, etc. que je pouvais utiliser pour faire tout ce que je voulais.

Peut-être que pour l'iPhone, des bibliothèques ont été écrites pour cela, mais est-ce si difficile de créer cette application simple vous-même? Après quelques recherches, je me suis rendu compte que je devais me pencher sur CFNetwork, CFHost, CFSocket, CFStream.

Question

Existe-t-il quelqu'un qui pourrait me guider vers un tutoriel ou poster le code lorsque vous avez deux boutons sur l'iPhone. [Démarrer le serveur] et [Se connecter au serveur]: le premier démarre un serveur TCP / IP sur un certain port et le second s'y connecte.

Une fois la connexion établie, le code permettant d'envoyer un simple message "Ping" au serveur une fois que le serveur en a reçu une réponse est envoyé au client par un message "Pong".

Cela serait vraiment utile. Mais peut-être que je demande beaucoup ici.

Était-ce utile?

La solution

ce tutoriel

Je l’ai adapté pour parler à mon serveur de socket et cela fonctionne à merveille. Il s'agit d'un code de test, il n'y a donc pas de réel problème avec les détails. il n'envoie qu'un message (votre identifiant de connexion) et reçoit une réponse qu'il affiche dans la console.

//
//  ViewController.m
//  zdelSocketTest01a
//
//

#import "ViewController.h"



@implementation ViewController
@synthesize inputNameField;
@synthesize joinView;

- (void)initNetworkCommunication {

    uint portNo = 5555;
    CFReadStreamRef readStream;
    CFWriteStreamRef writeStream;
    CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef)@"227.3.4.56", portNo, &readStream, &writeStream);
    inputStream = (__bridge NSInputStream *)readStream;
    outputStream = (__bridge NSOutputStream *)writeStream;

    [inputStream setDelegate:self];
    [outputStream setDelegate:self];

    [inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    [outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    [inputStream open];
    [outputStream open];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Release any cached data, images, etc that aren't in use.
}

#pragma mark - View lifecycle

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    [self initNetworkCommunication];
    messages = [[NSMutableArray alloc] init];
}

- (void)viewDidUnload
{
    [self setInputNameField:nil];
    [self setJoinView:nil];
    [self setJoinView:nil];
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
}

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
}

- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];
}

- (void)viewDidDisappear:(BOOL)animated
{
    [super viewDidDisappear:animated];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // Return YES for supported orientations
    return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}

- (IBAction)joinChat:(id)sender {

    NSString *response  = [NSString stringWithFormat:@"logon,%@", inputNameField.text];
    NSData *data = [[NSData alloc] initWithData:[response dataUsingEncoding:NSASCIIStringEncoding]];
    [outputStream write:[data bytes] maxLength:[data length]];

}
/*
 - (void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent {
 NSLog(@"stream event %i", streamEvent);
 }
 */

- (void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent {
    typedef enum {
        NSStreamEventNone = 0,
        NSStreamEventOpenCompleted = 1 << 0,
        NSStreamEventHasBytesAvailable = 1 << 1,
        NSStreamEventHasSpaceAvailable = 1 << 2,
        NSStreamEventErrorOccurred = 1 << 3,
        NSStreamEventEndEncountered = 1 << 4
    };
    uint8_t buffer[1024];
    int len;

    switch (streamEvent) {

        case NSStreamEventOpenCompleted:
            NSLog(@"Stream opened now");
            break;
        case NSStreamEventHasBytesAvailable:
            NSLog(@"has bytes");
            if (theStream == inputStream) {
                while ([inputStream hasBytesAvailable]) {
                    len = [inputStream read:buffer maxLength:sizeof(buffer)];
                    if (len > 0) {

                        NSString *output = [[NSString alloc] initWithBytes:buffer length:len encoding:NSASCIIStringEncoding];

                        if (nil != output) {
                            NSLog(@"server said: %@", output);
                        }
                    }
                }
            } else {
                NSLog(@"it is NOT theStream == inputStream");
            }
            break;
        case NSStreamEventHasSpaceAvailable:
            NSLog(@"Stream has space available now");
            break;


        case NSStreamEventErrorOccurred:
            NSLog(@"Can not connect to the host!");
            break;


        case NSStreamEventEndEncountered:

            [theStream close];
            [theStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

            break;

        default:
            NSLog(@"Unknown event %i", streamEvent);
    }

}
/*
 - (void) messageReceived:(NSString *)message {

 [messages addObject:message];
 [self.tView reloadData];

 }
 */

@end

votre fichier ViewController.h contiendrait

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController <NSStreamDelegate>
@property (weak, nonatomic) IBOutlet UITextField *inputNameField;
@property (weak, nonatomic) IBOutlet UIView *joinView;
- (IBAction)joinChat:(id)sender;


@end
NSInputStream *inputStream;
NSOutputStream *outputStream;
NSMutableArray * messages;

NOOBS ONLY: vous devez lier votre bouton et votre champ de texte en appuyant sur CTRL et en faisant glisser l'objet dans la fenêtre de code. lorsque vous faites cela, les propriétés ci-dessus seront automatiquement créées. consultez ce didacticiel vidéo si vous êtes pris au piège

NOOBS ONLY 2: cette prise sera affichée dans la CONSOLE PANE de XCODE. Dans le coin supérieur droit de la fenêtre de votre xcode, cliquez sur CACHER OU MONTRER LA ZONE DE DÉBOGAGE (demandez de l'aide si nécessaire).

construit et testé (simulateur et appareil) sur un macbook doté de 2 Go de mémoire, utilisant xcode 4.2 pour Snow Leopard.

Autres conseils

Je recommande ce qui suit: Socket Async de cacao

Il existe également un exemple de projet de base sur le site pour vous aider à démarrer. J'ai eu beaucoup de succès avec ce cadre.

Je m'attendrais à ce que vous souhaitiez que votre serveur soit déjà démarré, après quoi vous aurez uniquement besoin d'un " Connexion au serveur " bouton, puis votre "Ping". Sinon, vous avez besoin d’un processus distinct sur votre serveur qui répond au message "Démarrer le serveur". message et démarre le serveur.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top