Подтвердить что ты не робот

IPhone TCP/IP Socket Server/Клиентская программа

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

Моя цель

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

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

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

Фон

Я работал с сокетами в прошлом, но только в 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-message".

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

4b9b3361

Ответ 1

этот учебник, чтобы создать приложение для примера чата, работает очень хорошо и довольно просто (любой iphone noob, как и я, может заставить его работать, EVEN IN SIMULATOR MODE он подключается к внешнему серверу сокетов).

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

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

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

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

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

Ответ 2

Я рекомендую следующее: Cocoa Async Socket

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

Ответ 3

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