سؤال

لقد قرأت الكثير من الأسئلة بخصوص هذا الموضوع على هذا الموقع ولكنهم لم يجيبوا على سؤالي.إذا كنت لا تستطيع أن تكون ### حول هدفي أو خلفيتي، فانتقل إلى السؤال.

هدفي

هو إنشاء خادم يمكن تشغيله على نظام التشغيل Mac OS X 10.4+ والإصدارات الأحدث، ونقله إلى نظام التشغيل Windows XP/Vista (لا توجد فكرة عن كيفية القيام بذلك حتى الآن، ولكن هذه مشكلة في وقت لاحق).

ثم اجعل iPhone هو العميل القادر على رؤية أسماء أجهزة الكمبيوتر التي تقوم بتشغيل الخادم (من خلال WiFi).يمكن لمستخدم iPhone بعد ذلك تحديد اسم الكمبيوتر للاتصال بالخادم الموجود على هذا الكمبيوتر.

بعد ذلك يمكنهم إرسال رسائل نصية بسيطة لبعضهم البعض.على سبيل المثال، يرسل iPhone عبارة "Knock Knock" ويستجيب الخادم "من هناك؟".أو عميل بسيط:"Ping"، يستجيب الخادم "Pong" سيكون على ما يرام.

خلفية

لقد عملت مع مآخذ التوصيل في الماضي، ولكن فقط في Visual Basic 6 مع WINSOCKET.dll كان من السهل جدًا إنشاء خادم TCP/IP.

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

مع العميل كنت بحاجة فقط إلى القيام بما يلي للاتصال.

client.connect(localhost, 12203);

كانت هناك بعض عمليات الاسترجاعات المتاحة مثل الاتصال والإغلاق وdataArrival وما إلى ذلك.والتي يمكنني استخدامها لفعل أي شيء أريده.

ربما توجد مكتبات مخصصة لجهاز iPhone، ولكن هل من الصعب إنشاء هذا التطبيق البسيط بنفسك؟بعد إجراء بعض الأبحاث، أدركت أنه يتعين علي البحث في مجال CFNetwork وCFHost وCFSocket وCFStream.

سؤال

هل هناك أي شخص يمكنه إرشادي إلى برنامج تعليمي أو نشر الرمز الذي يحتوي على زرين على iPhone.[Start Server] و[Connect to Server] حيث سيقوم الأول بتشغيل خادم 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.

نصائح أخرى

أوصي بما يلي:مقبس الكاكاو غير المتزامن

يوجد أيضًا نموذج أساسي للمشروع على الموقع لتبدأ به.لقد حققت نجاحًا جيدًا في العمل مع هذا الإطار.

أتوقع أنك تريد أن يكون الخادم الخاص بك قد بدأ بالفعل، وبعد ذلك ستحتاج فقط إلى زر "الاتصال بالخادم"، ثم "Ping".بخلاف ذلك، فأنت بحاجة إلى عملية منفصلة على صندوق الخادم الخاص بك والتي تستجيب لرسالة "بدء الخادم" وتبدأ تشغيل الخادم.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top