2009-09-17 38 views
20

Tôi đã đọc rất nhiều câu hỏi về chủ đề này trên trang web này tuy nhiên họ không yên tĩnh trả lời câu hỏi của tôi. Nếu bạn không thể ### về mục tiêu hoặc nền của tôi, hãy bỏ qua câu hỏi.Chương trình Máy chủ/Máy khách Ổ cắm TCP/IP của iPhone

My Goal

là để xây dựng một máy chủ có thể chạy trên Mac OS X 10.4+ và sau, cổng nó để Windows XP/Vista (không có ý tưởng làm thế nào để làm điều đó, nhưng đó là một vấn đề cho sau này).

Sau đó, để iPhone là ứng dụng khách có thể xem tên máy tính đang chạy máy chủ (qua WiFi). Người dùng iPhone sau đó có thể chọn tên máy tính để kết nối với máy chủ trên máy tính đó.

Sau đó, họ có thể gửi tin nhắn văn bản đơn giản cho nhau. Ví dụ, iPhone gửi 'Knock Knock' và máy chủ trả lời 'Ai ở đó?'. Hoặc một khách hàng đơn giản: 'Ping', máy chủ trả lời 'Pong' sẽ làm tốt.

nền

Tôi đã làm việc với ổ cắm trong quá khứ, nhưng chỉ trong Visual Basic 6 với WINSOCKET.dll nó là rất dễ dàng để tạo ra một máy chủ TCP/IP.

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

Với khách hàng, tôi chỉ cần thực hiện các thao tác sau để kết nối.

client.connect(localhost, 12203); 

Có một số cuộc gọi lại có sẵn như kết nối, đóng, dữ liệu, vv mà tôi có thể sử dụng để làm bất cứ điều gì mình muốn.

Có lẽ đối với iPhone có thư viện được viết cho nó, nhưng khó có thể tự tạo ứng dụng đơn giản này không? Sau khi thực hiện một số nghiên cứu, tôi hiểu rằng tôi phải tìm trong lĩnh vực CFNetwork, CFHost, CFSocket, CFStream.

Câu hỏi

Có ai có thể hướng dẫn cho tôi đến một hướng dẫn hoặc gửi mã nơi bạn có hai nút trên iPhone. [Start Server] và [Connect to Server], nơi đầu tiên sẽ bắt đầu một máy chủ TCP/IP trên một cổng nhất định và thứ hai kết nối với nó.

Sau khi kết nối đã được thực hiện có thể cũng là mã để gửi một thông điệp 'Ping' đơn giản đến máy chủ sau khi máy chủ nhận được phản hồi này với thông điệp 'Pong' tới máy khách.

Điều đó thực sự hữu ích. Nhưng có lẽ tôi đang yêu cầu nhiều ở đây.

+0

bạn không hỏi quá nhiều NẾU bạn ít nhất là bình luận TẤT CẢ câu trả lời. bỏ phiếu cho một giải pháp sẽ được thực sự tốt đẹp, quá. ;) –

Trả lời

17

this tutorial để tạo ứng dụng mẫu trò chuyện hoạt động rất tốt và khá đơn giản (mọi iphone noob, như tôi, có thể làm cho nó hoạt động, NGAY CẢ MÔ PHỎNG MÔ HÌNH nó kết nối với máy chủ socket bên ngoài).

tôi đã điều chỉnh nó để nói về máy chủ socket của tôi và nó hoạt động như một sự quyến rũ. đây là mã thử nghiệm, vì vậy không có mối quan tâm thực sự với kết thúc lỏng lẻo. nó chỉ gửi một tin nhắn (id đăng nhập của bạn) và nhận được một câu trả lời, nó hiển thị trong giao diện điều khiển.

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

tập tin ViewController.h của bạn sẽ chứa

#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 CHỈ: bạn phải liên kết nút của bạn và lĩnh vực văn bản bằng cách nhấn Control và kéo các đối tượng vào cửa sổ mã. khi bạn làm điều đó, các thuộc tính ở trên sẽ tự động được tạo. kiểm tra this video tutorial nếu bạn đang stumped

NOOBS ONLY 2: ổ cắm này sẽ xuất ra trong CONSOLE PANE của XCODE. ở góc trên bên phải của cửa sổ xcode của bạn, nhấp HIDE HOẶC HIỂN THỊ KHU VỰC L DEI (yêu cầu trợ giúp nếu cần).

được xây dựng và thử nghiệm (mô phỏng và thiết bị) trên macbook có bộ nhớ 2GB, sử dụng xcode 4.2 cho báo tuyết.

+2

cảm ơn bạn rất nhiều. Hữu ích cho tôi. – piggy

+1

chúng ta có thể có mã nguồn cho bản sao làm việc không? –

+0

@FahimParkar đây là mã nguồn cho phiên bản làm việc. nếu bạn thấy điều này hữu ích, tôi hy vọng bạn nhớ bỏ phiếu UP, nếu có thể. tks. ;) –

1

Tôi hy vọng bạn muốn máy chủ của mình đã được bắt đầu và sau đó bạn chỉ cần nút "Kết nối với máy chủ" và sau đó là "Ping" của bạn. Nếu không, bạn cần một quá trình riêng biệt trên hộp máy chủ của bạn để phản hồi thông báo "Start Server" và khởi động máy chủ.

+0

Ồ, vậy đó là cách nó hoạt động? Để có thể phát hiện một máy chủ như một máy khách, bạn gửi một tin nhắn đến một dải địa phương nhất định (ví dụ: 192.168.1.1 -> 255) và mọi máy chủ trả lời tin nhắn bạn đưa vào TableView của bạn. Được rồi, tôi sẽ hiểu. – Mark

+0

Có cách nào bạn có thể giúp tôi với phần thứ hai của câu hỏi của tôi không? Làm thế nào để có được ping giữa hai? – Mark

+2

cổng truyền phát của Google. –

3

Tôi khuyên bạn nên điều sau đây: Cocoa Async Socket

Ngoài ra còn có một dự án ví dụ cơ bản trên trang web để giúp bạn bắt đầu. Tôi đã thành công tốt khi làm việc với khuôn khổ đó.

Các vấn đề liên quan