1

我按下按钮连接到服务器(TCP),但我不知道它是否连接。这是代码的一部分:

[self connectToServerUsingCFStream:msg portNo:50000];

    if(readStream && writeStream)
    {
        NSString *newText = [[NSString alloc] initWithFormat:@"Connected!! :)"]; 
        statusText.text = newText;
        [newText release];
        pingButton.hidden = NO;
    }
    else
    {
        NSString *newText = [[NSString alloc] initWithFormat:@"Connection unsuccessful :("]; 
        statusText.text = newText;
        [newText release];
    }

即使服务器离线,我也总是得到“已连接!!:)”:s

4

2 回答 2

7

以下连接方法的人的解决方案:

CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, 
                                   (CFStringRef) urlStr, 
                                   portNo, 
                                   &readStream, 
                                   &writeStream);

if (readStream && writeStream) 
{
    CFReadStreamSetProperty(readStream, 
                            kCFStreamPropertyShouldCloseNativeSocket, 
                            kCFBooleanTrue);
    CFWriteStreamSetProperty(writeStream, 
                             kCFStreamPropertyShouldCloseNativeSocket, 
                             kCFBooleanTrue);

    iStream = (NSInputStream *)readStream;
    [iStream retain];
    [iStream setDelegate:self];
    [iStream scheduleInRunLoop:[NSRunLoop currentRunLoop] 
                       forMode:NSDefaultRunLoopMode];
    [iStream open];

    oStream = (NSOutputStream *)writeStream;
    [oStream retain];
    [oStream setDelegate:self];
    [oStream scheduleInRunLoop:[NSRunLoop currentRunLoop] 
                       forMode:NSDefaultRunLoopMode];
    [oStream open];         
} 

正在使用

-(void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent

像这样:

-(void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent
{
NSString *io;
if (theStream == iStream) io = @">>";
else io = @"<<";

NSString *event;
switch (streamEvent)
{
    case NSStreamEventNone:
        event = @"NSStreamEventNone";
        statusText.text =  @"Can not connect to the host!";
        break;

    case NSStreamEventOpenCompleted:
        event = @"NSStreamEventOpenCompleted";
        pingButton.hidden = NO;
        statusText.text = @"Connected";
        break;

    case NSStreamEventHasBytesAvailable:
        event = @"NSStreamEventHasBytesAvailable";
        if (theStream == iStream)
        {
            //read data
            uint8_t buffer[1024];
            int len;
            while ([iStream hasBytesAvailable])
            {
                len = [iStream read:buffer maxLength:sizeof(buffer)];
                if (len > 0)
                {
                    NSString *output = [[NSString alloc] initWithBytes:buffer length:len encoding:NSASCIIStringEncoding];
                    NSData *theData = [[NSData alloc] initWithBytes:buffer length:len];
                    if (nil != output)
                    {
                        //do something with data
                    }
                }
            }
        }
        break;

    case NSStreamEventHasSpaceAvailable:
        event = @"NSStreamEventHasSpaceAvailable";
        if (theStream == oStream)
        {
            //send data
            uint8_t buffer[11] = "I send this";             
            int len;

            len = [oStream write:buffer maxLength:sizeof(buffer)];
            if (len > 0)
            {
                NSLog(@"Command send");
                [oStream close];
            }
        }

        break;

    case NSStreamEventErrorOccurred:
        event = @"NSStreamEventErrorOccurred";
        statusText.text = @"Can not connect to the host!";
        pingButton.hidden = YES;
        break;

    case NSStreamEventEndEncountered:
        event = @"NSStreamEventEndEncountered";
        statusText.text = @"Connection closed by the server.";
        pingButton.hidden = YES;
        [theStream close];
        [theStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
        [theStream release];
        theStream = nil;
        break;

    default:
        event = @"** Unknown";
}

NSLog(@"%@ : %@", io, event);
}

(据我所知!)这篇文章的学分归属于deksa(虽然我不知道谁是创作者,因为我在网上看到过这个几次,包括这里 o SO)。这段代码被我稍微修改了一下(pingButton,statusText),如果你想要原始代码,请转到前面提到的链接。

Apple 开发者网站也有这方面的一些信息。

就像我说过的,我在网上看到过一些类似这样的东西,但现在我明白,连接后发生的一切都是“自动的”;例如,如果服务器使用 暂停read()case NSStreamEventHasSpaceAvailable:则将自动调用 ,并且将运行其中的所有代码。

现在我认为这个问题已经回答了。

于 2011-06-16T18:47:33.027 回答
1

尽管您没有提供足够的信息,但我建议对 HTTP使用ASIHTTPRequest ,对 TCP 和 UDP使用AsyncSocket 。如果建立了连接,将触发回调方法,

我不得不说,我对 CFNetwork 的经验非常有限,但对我来说,好像你只是在测试流对象是否存在(if(readStream && writeStream))。
快速浏览一下CFNetwork Programming Guide: Working with Read Streams告诉我,你必须用 来打开它CFReadStreamOpen(),如果它真的打开了流,这个函数将返回一个布尔值。

if (!CFReadStreamOpen(myReadStream)) {
    CFStreamError myErr = CFReadStreamGetError(myReadStream);
    // An error has occurred.
        if (myErr.domain == kCFStreamErrorDomainPOSIX) {
        // Interpret myErr.error as a UNIX errno.
        } else if (myErr.domain == kCFStreamErrorDomainMacOSStatus) {
        // Interpret myErr.error as a MacOS error code.
            OSStatus macError = (OSStatus)myErr.error;
        // Check other error domains.
    }
}

顺便说一句:
而不是

NSString *newText = [[NSString alloc] initWithFormat:@"Connected!! :)"]; 
statusText.text = newText;
[newText release];

你可以写statusText.text = @"Connected!! :)";

于 2011-06-15T11:22:34.653 回答