Pergunta

Eu li um monte de perguntas sobre este assunto neste site no entanto que não tranquila resposta à minha pergunta. Se você não pode estar ### sobre o meu objetivo ou fundo pular para a questão.

Meu objetivo

É construir um servidor que pode ser executado no Mac OS X 10.4+ e, mais tarde, a porta-lo para o Windows XP / Vista (nenhuma idéia de como fazer isso ainda, mas isso é um problema para mais tarde).

Então deixe o iPhone ser o cliente que é capaz de ver os nomes dos computadores que estão executando o servidor (através de Wi-Fi). O usuário do iPhone pode então selecionar o nome do computador para se conectar ao servidor no mesmo computador.

Depois que eles podem enviar mensagens de texto simples para outro. Por exemplo, o iPhone envia 'Knock Knock' e as responde servidor 'Quem está aí?'. Ou um cliente simples:. 'Ping', responde servidor 'Pong' vai fazer muito bem

Fundo

Eu tenho trabalhado com tomadas no passado, mas somente em Visual Basic 6 com o WINSOCKET.dll era muito fácil criar um servidor TCP / IP.

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

Com o cliente eu só precisava fazer o seguinte para se conectar.

client.connect(localhost, 12203);

Houve algumas chamadas de retorno disponíveis, como conexão, fechar, DataArrival, etc. que eu poderia usar para fazer o que quiser.

Talvez para o iPhone existem bibliotecas escritas para ele, mas é tão difícil de criar esta aplicação simples a si mesmo? Depois de fazer algumas pesquisas eu entendo que eu tenho que olhar na área de CFNetwork, CFHost, CFSocket, CFStream.

Pergunta

Existe alguém que poderia guiar-me para um tutorial ou postar o código onde você tem dois botões no iPhone. [Start Server] e [Conectar ao Servidor], onde o primeiro vai iniciar um servidor TCP / IP em uma determinada porta eo segundo se conecta a ele.

Depois de uma conexão foi feita talvez também o código para enviar um simples 'Ping'-mensagem para o servidor depois que o servidor recebe este responde com um' Pong'-mensagem para o cliente.

Isso seria realmente útil. Mas talvez eu estou pedindo para muito aqui.

Foi útil?

Solução

este tutorial para criar um aplicativo de exemplo de chat funciona muito bem e é bastante simples (qualquer Noob iphone, como eu, pode fazê-lo funcionar, mesmo em SIMULADOR MODO ele se conecta ao servidor de soquete externo).

i adaptou-o para falar o meu servidor de soquete e funciona como um encanto. este é o código de teste, então não há nenhuma preocupação real com pontas soltas. ele só envia uma mensagem (o seu ID de logon) e recebe uma volta resposta, que ele mostra no 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

seu arquivo ViewController.h conteria

#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: você deve ligar o seu botão e campo de texto pressionando CONTROL e arrastando o objeto na janela de código. quando você faz isso, as propriedades acima será criado automaticamente. verificar este vídeo tutorial se você está perplexo

NOOBS APENAS 2: A saída será tomada no console PANE do Xcode. no canto superior direito da janela do Xcode, clique em ocultar ou mostrar a área de depuração (pedir ajuda se necessário).

construído e testado (simulador e dispositivo) em um MacBook com 2 GB de memória, usando o Xcode 4.2 para leopardo da neve.

Outras dicas

Eu recomendo o seguinte: Cacau assíncrono soquete

Há também um projeto de exemplo básico no site para você começar. Eu tive um bom sucesso trabalhando com esse quadro.

Eu esperaria que você quer que seu servidor para já ser iniciado, e então você só precisa de um botão "Conectar ao Servidor", e então o seu "Ping". Caso contrário, você precisa de um processo separado em sua caixa servidor que responde a mensagem "Start Server" e inicia o servidor.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top