【问题标题】:iPhone TCP/IP Socket Server/Client ProgramiPhone TCP/IP Socket 服务器/客户端程序
【发布时间】:2010-11-29 02:36:12
【问题描述】:

我在这个网站上阅读了很多关于这个主题的问题,但是他们没有安静地回答我的问题。如果您不能### 关于我的目标或背景,请跳至问题。

我的目标

是构建一个可以在 Mac OS X 10.4+ 及更高版本上运行的服务器,将其移植到 Windows XP/Vista(目前还不知道怎么做,但这是以后的问题)。

然后让 iPhone 成为能够查看运行服务器的计算机名称的客户端(通过 WiFi)。然后,iPhone 用户可以选择计算机名称以连接到该计算机上的服务器。

之后,他们可以互相发送简单的短信。例如,iPhone 发送“Knock Knock”,服务器响应“Who is there?”。或者一个简单的客户端:“Ping”,服务器响应“Pong”就可以了。

背景

我过去曾使用过套接字,但仅在带有 WINSOCKET.dll 的 Visual Basic 6 中,创建 TCP/IP 服务器非常容易。

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

对于客户端,我只需要执行以下操作即可连接。

client.connect(localhost, 12203);

有一些可用的回调函数,例如 connect、close、dataArrival 等,我可以用它们来做任何我想做的事情。

也许为 iPhone 编写了一些库,但是自己创建这个简单的应用程序有那么难吗?在做了一些研究之后,我了解到我必须研究 CFNetwork、CFHost、CFSocket、CFStream 领域。

问题

有没有人可以指导我学习教程或发布你在 iPhone 上有两个按钮的代码。 [ Start Server ] 和 [ Connect to Server] 其中第一个将在某个端口上启动 TCP/IP 服务器,第二个连接到它。

在建立连接后,可能还有代码向服务器发送一个简单的“Ping”消息,服务器收到此消息后会向客户端发送一个“Pong”消息。

那真的很有帮助。但也许我在这里要求太多了。

【问题讨论】:

  • 如果您至少评论每个答案,您并没有要求太多。为解决方案投票也将非常好。 ;)

标签: iphone sockets connection communication


【解决方案1】:

this tutorial 创建一个聊天示例应用程序非常好用并且非常简单(像我这样的任何 iphone 菜鸟都可以让它工作,即使在模拟器模式下它也连接到外部套接字服务器)。

我调整了它来与我的套接字服务器通信,它就像一个魅力。这是测试代码,所以没有真正的问题。它只发送一条消息(您的登录 ID)并收到回复,它会显示在控制台中。

//
//  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 并将对象拖到代码窗口中来链接按钮和文本字段。当您这样做时,将自动创建上述属性。检查this video tutorial如果你被难住了

NOOBS ONLY 2:此套接字将在 XCODE 的 CONSOLE PANE 中输出。在 xcode 窗口的右上角,单击 HIDE OR SHOW THE DEBUG AREA(必要时寻求帮助)。

在具有 2GB 内存的 macbook 上构建和测试(模拟器和设备),使用 xcode 4.2 for snow leopard。

【讨论】:

  • @FahimParkar 这是工作版本的源代码。如果你觉得这很有用,我希望你记得投票,如果可能的话。 tks。 ;)
  • @tonygil:你能看看this question。你的 cmets 会很有价值...
  • @FahimParkar 您还需要什么?我可以在下周的某个时候给你发一份副本(这周我要为一个 android 客户端的大量交付而发疯)。
  • @tonygil : 没关系..我从tekritisoftware.com/sites/default/files/…管理
  • @tony gil 你能指导我到服务器端代码(php 代码)吗? php如何监听来自ios的消息并回复?
【解决方案2】:

我推荐以下内容: Cocoa Async Socket

网站上还有一个基本示例项目可以帮助您入门。我在使用该框架方面取得了巨大成功。

【讨论】:

    【解决方案3】:

    我希望您希望您的服务器已经启动,然后您只需要一个“连接到服务器”按钮,然后是您的“Ping”。否则,您需要在服务器上设置一个单独的进程来响应“启动服务器”消息并启动服务器。

    【讨论】:

    • 哦,原来是这样的?为了能够将服务器检测为客户端,您将消息发送到某个本地 IP 范围(例如 192.168.1.1 -> 255)以及回复您放入 TableView 中的该消息的每个服务器。好的,我会明白的。
    • 还有什么方法可以帮助我解决我的问题的第二部分吗?如何获得两者之间的ping?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-09
    • 1970-01-01
    相关资源
    最近更新 更多