iPhone TCP / IP Socket Serveur / Client programme

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

Mon Objectif Est De

Est de construire un serveur qui peut fonctionner sur Mac OS X 10.4 + et plus tard, le porter sur Windows XP/Vista (aucune idée de comment le faire encore, mais c'est un problème pour plus tard).

Ensuite, laissez l'iPhone être le client capable de voir les noms d'ordinateurs qui sont exécution du serveur (via WiFi). L'utilisateur de l'iPhone pouvez ensuite sélectionner le nom de l'ordinateur pour se connecter au serveur sur l'ordinateur.

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

Arrière-plan

J'ai travaillé avec des sockets dans le passé, mais seulement dans Visual Basic 6 avec le WINSOCKET.DLL il était très facile de créer un serveur TCP/IP.

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

Avec le client, j'avais seulement besoin de faire ce qui suit pour me connecter.

client.connect(localhost, 12203);

Il y avait des rappels disponibles comme connect, close, dataArrival, etc. que je pourrais utiliser pour faire ce que je veux.

Peut-être pour l'iPhone il y a des bibliothèques écrites pour elle, mais est-il si difficile de créer cette application simple vous-même? Après avoir fait quelques recherches, je comprends que je dois regarder dans le domaine de CFNetwork, CFHost, CFSocket, CFStream.

Question

Y a-t-il quelqu'un qui pourrait me guider vers un tutoriel ou poster le code où vous avez deux boutons sur l'iPhone. [Démarrer le serveur ] et [se connecter au serveur] où le premier démarrera un serveur TCP/IP sur un certain port et le second s'y connectera.

Après une connexion a été faite peut-être aussi le code pour envoyer un simple message'ping' au serveur après que le serveur reçoit cela répond avec un message 'Pong' au client.

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

22
demandé sur Will 2009-09-17 14:35:08

3 réponses

Ce tutoriel pour créer un exemple d'application de chat fonctionne très bien et est assez simple (tout noob iphone, comme moi, peut le faire fonctionner, même en mode simulateur, il se connecte au serveur de socket externe).

Je l'ai adapté pour parler de mon serveur socket et cela fonctionne comme un charme. c'est un code de test, donc il n'y a pas de réel souci avec les extrémités libres. il envoie seulement un message (votre id 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 ViewController.h le fichier 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 uniquement: 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. Vérifiez ce tutoriel vidéo Si vous êtes perplexe

NOOBS seulement 2: ce socket sortira dans le volet CONSOLE de XCODE. dans le coin supérieur droit de votre fenêtre xcode, cliquez sur Masquer ou afficher la zone de débogage (demandez de l'aide si nécessaire).

Construit et testé (simulateur et appareil) sur un macbook avec 2 Go de mémoire, en utilisant xcode 4.2 Pour snow leopard.

18
répondu tony gil 2013-04-23 14:10:06

Je recommande ce qui suit: Socket Asynchrone Cocoa

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

3
répondu Kongress 2012-12-05 16:33:02

Je m'attendrais à ce que vous souhaitiez que votre serveur soit déjà démarré, et alors vous n'auriez besoin que d'un bouton "Se connecter au serveur" , puis de votre "Ping". Sinon, vous avez besoin d'un processus séparé sur votre boîte de serveur qui répond au message "Démarrer le serveur" et démarre le serveur.

1
répondu Chris Kline 2009-09-28 01:03:24