9

我必须使用套接字编程为 iOS 创建一个聊天应用程序,我的 IP 地址是192.168.0.57:9300. 我使用了Raywenderlich套接字编程示例,接收数据正常但发送不工作,没有任何错误或崩溃。我的代码如下。

打开流的代码

- (void) initNetworkCommunication {

    CFReadStreamRef readStream;
    CFWriteStreamRef writeStream;
    CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef)@"192.168.0.57", 9300, &readStream, &writeStream);

    inputStream = (NSInputStream *)readStream;
    outputStream = (NSOutputStream *)writeStream;
    [inputStream setDelegate:self];
    [outputStream setDelegate:self];
    [inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    [outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    [inputStream open];
    [outputStream open];    
}

发送数据的代码

- (IBAction)sendMessage:(id)sender
{
        NSString *response  = @"lets start chat";
        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);

    switch (streamEvent) {

        case NSStreamEventOpenCompleted:
            NSLog(@"Stream opened");
            break;
        case NSStreamEventHasBytesAvailable:

            if (theStream == inputStream) {

                uint8_t buffer[1024];
                int len;

                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(@"\nreciving data------%@,buffer);

                            [self messageReceived:output];

                        }
                    }
                }
            }
            break;


        case NSStreamEventErrorOccurred:

            NSLog(@"Can not connect to the host!");
            break;

        case NSStreamEventEndEncountered:

            [theStream close];
            [theStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
            [theStream release];
            theStream = nil;

            break;
        default:
            NSLog(@"Unknown event");
    }

}
Message sending
    - (void) messageReceived:(NSString *)message {

        [self.messages addObject:message];
        [self.tView reloadData];
        NSIndexPath *topIndexPath = [NSIndexPath indexPathForRow:messages.count-1 
                                                       inSection:0];
        [self.tView scrollToRowAtIndexPath:topIndexPath 
                          atScrollPosition:UITableViewScrollPositionMiddle 
                                  animated:YES];

    }

请给我建议。

4

3 回答 3

5

您应该在回复末尾添加“\n”,如下所示:

- (IBAction)sendMessage:(id)sender
{
        NSString *response  = @"lets start chat\n";
        ////your code
}

这对我有用,但我的问题是我无法使用该功能接收数据(void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent

于 2013-04-27T15:05:21.733 回答
1

我发现写一个单独的线程为我解决了这个问题。
这是有道理的,因为人们不应该真正在主线程上进行网络操作。
这是我的代码:

dispatch_async(dispatch_get_global_queue(QOS_CLASS_BACKGROUND, 0), ^(void) {
    NSData *data = [[NSData alloc] initWithData:[response dataUsingEncoding:NSASCIIStringEncoding]];
    NSInteger len = [outputStream write:[data bytes] maxLength:[data length]];
    NSLog(@"Len = %ld", len);
});

还有一点需要注意的是,NSStreamEventOpenCompleted 事件被调用了两次。当每个输入和输出流打开时一次。因此,需要注意不要在事件发生之前写入输出流。

于 2014-12-07T16:41:58.157 回答
1

我有类似的问题。通过在字符串中附加换行符和换行符来解决它。

- (IBAction)sendMessage:(id)sender {

        NSString *response  = @"lets start chat\r\n\r\n";
        NSData *data = [[NSData alloc] initWithData:[response dataUsingEncoding:NSASCIIStringEncoding]];
        [outputStream write:[data bytes] maxLength:[data length]]; 
}
于 2014-10-17T05:10:28.883 回答