Серверная / Клиентская программа Сокета iPhone TCP / IP для iPhone

StackOverflow https://stackoverflow.com/questions/1437993

Вопрос

Я прочитал много вопросов по этой теме на этом веб-сайте, однако они спокойно не ответили на мой вопрос.Если вы не можете быть ### в курсе моей цели или предыстории, переходите к вопросу.

Моя Цель

Заключается в создании сервера, который может работать на Mac OS X 10.4+ и более поздних версиях, портировании его на Windows XP / Vista (пока не знаю, как это сделать, но это проблема на потом).

Затем пусть iPhone будет клиентом, который может видеть имена компьютеров, на которых запущен сервер (через Wi-Fi).Затем пользователь iPhone может выбрать имя компьютера для подключения к серверу на этом компьютере.

После этого они могут отправлять друг другу простые текстовые сообщения.Например, iPhone отправляет "Тук-тук", а сервер отвечает "Кто там?".Или простой клиент:"Ping", сервер отвечает, что "Pong" подойдет просто отлично.

Предыстория

Я работал с сокетами в прошлом, но только в Visual Basic 6 с WINSOCKET.dll создать сервер TCP / IP было очень просто.

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

С клиентом мне нужно было только выполнить следующее для подключения.

client.connect(localhost, 12203);

Были доступны некоторые обратные вызовы, такие как connect, close, dataArrival и т.д.который я мог бы использовать, чтобы делать все, что захочу.

Возможно, для iPhone есть библиотеки, написанные для него, но так ли сложно создать это простое приложение самостоятельно?Проведя некоторые исследования, я понимаю, что мне нужно заглянуть в область CFNetwork, CFHost, CFSocket, CFStream.

Вопрос

Есть ли кто-нибудь, кто мог бы подвести меня к руководству или опубликовать код, где у вас есть две кнопки на iPhone?[Запустить сервер] и [Подключиться к серверу], где первый запускает сервер TCP / IP на определенном порту, а второй подключается к нему.

После установления соединения, возможно, также код для отправки простого Ping-сообщения на сервер после того, как сервер получит это, ответит сообщением Pong клиенту.

Это действительно было бы полезно.Но, возможно, я прошу здесь слишком многого.

Это было полезно?

Решение

этот учебник пример создания приложения для чата работает очень хорошо и довольно просто (любой новичок в iPhone, вроде меня, может заставить его работать, ДАЖЕ В РЕЖИМЕ СИМУЛЯТОРА он подключается к внешнему серверу сокетов).

я адаптировал его для работы с моим сервером сокетов, и он работает как по волшебству.это тестовый код, так что нет никакой реальной проблемы с незакрепленными концами.он отправляет только одно сообщение (ваш идентификатор входа в систему) и получает ответ обратно, который отображается в консоли.

//
//  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

ваш файл ViewController.h будет содержать

#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;

ТОЛЬКО ДЛЯ НОВИЧКОВ:вы должны связать свою кнопку и текстовое поле, нажав CONTROL и перетащив объект в окно кода.когда вы это сделаете, указанные выше свойства будут созданы автоматически.проверить этот видеоурок если вы зашли в тупик

ВСЕГО 2 новичка:этот сокет будет выводиться в ПАНЕЛИ КОНСОЛИ XCODE.в правом верхнем углу окна xcode нажмите СКРЫТЬ ИЛИ ПОКАЗАТЬ ОБЛАСТЬ ОТЛАДКИ (при необходимости обратитесь за помощью).

собран и протестирован (симулятор и устройство) на macbook с 2 ГБ памяти с использованием xcode 4.2 для snow leopard.

Другие советы

Я рекомендую следующее:Асинхронный Сокет Cocoa

На сайте также есть базовый пример проекта, который поможет вам начать работу.Я добился хорошего успеха, работая с этим фреймворком.

Я бы ожидал, что вы захотите, чтобы ваш сервер уже был запущен, и тогда вам понадобится только кнопка "Подключиться к серверу", а затем ваш "Ping".В противном случае вам понадобится отдельный процесс на вашем сервере, который отвечает на сообщение "Запустить сервер" и запускает сервер.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top