带有 runloop 的异步 CFStream 网络

发布于 2024-10-04 04:15:30 字数 2330 浏览 5 评论 0原文

我正在尝试使用 runloop 实现异步 tcp 网络。 目前我设法连接,但是当我尝试发送某些内容时,我发现 -1 字节已被写入 - 但 CFWriteStreamCopyError 返回 null。

下面的代码示例,第一个函数连接,第二个函数发送一条简单的消息。 任何帮助将不胜感激,包括随机错误发现(我是 Objective-C 和 iPhone 开发的新手)。

struct header
{
    uint32_t length;
    uint32_t type;
} header;

- (void) connect
{
    NSLog(@"Attempting to (re)connect to %@:%d", m_host, m_port);
    while(TRUE)
    {
        CFHostRef host = CFHostCreateWithName(kCFAllocatorDefault, (CFStringRef)m_host);
        if (!host)
        {
            NSLog(@"Error resolving host %@", m_host);
            [NSThread sleepForTimeInterval:5.0];
            continue;
        }
        CFStreamCreatePairWithSocketToCFHost(kCFAllocatorDefault, host , m_port, &m_in, &m_out);
        CFRelease(host);

        if (!m_in)
        {
            NSLog(@"Error");
        }

        CFStreamClientContext context = {0, self,nil,nil,nil};

        if (CFReadStreamSetClient(m_in, kCFStreamEventHasBytesAvailable | kCFStreamEventErrorOccurred | kCFStreamEventEndEncountered, networkReadEvent, &context))
        {
            CFReadStreamScheduleWithRunLoop(m_in, CFRunLoopGetCurrent(),kCFRunLoopCommonModes);
        }

        if (CFWriteStreamSetClient(m_out, kCFStreamEventErrorOccurred | kCFStreamEventEndEncountered, networkWriteEvent, &context))
        {
            CFWriteStreamScheduleWithRunLoop(m_out, CFRunLoopGetCurrent(),kCFRunLoopCommonModes);
        }


        BOOL success = CFReadStreamOpen(m_in);
        CFErrorRef error = CFReadStreamCopyError(m_in);
        if (!success || (error && CFErrorGetCode(error) != 0))
        {
            NSLog(@"Connect error %s : %d", CFErrorGetDomain(error), CFErrorGetCode(error));
            [NSThread sleepForTimeInterval:5.0];
        }
        else 
        {
            NSLog(@"Connected");
            break;
        }
    }


    [self startSession];
}

- (void) startSession
{
    struct header hh;
    hh.type = RTR_CREATE_SESSION;
    hh.length = 0;
    CFIndex res = CFWriteStreamWrite(self.m_out, (const UInt8*)&hh, sizeof(hh));
    NSLog(@"Written %d", res);

    CFErrorRef error = CFWriteStreamCopyError(self.m_out);
    if (error)
    {
        NSLog(@"Read error %s : %d", CFErrorGetDomain(error), CFErrorGetCode(error));
        CFRelease(error);
    }
}

I am trying to implement async tcp networking with runloop.
currently I manage to connect, but when I try to send something I get that -1 bytes have been written - but CFWriteStreamCopyError returns null.

code sample below, first function connects, second send a simple message.
any help will be appreciated, including random bug spotting (I am new to objective-c and to iphone development in general).

struct header
{
    uint32_t length;
    uint32_t type;
} header;

- (void) connect
{
    NSLog(@"Attempting to (re)connect to %@:%d", m_host, m_port);
    while(TRUE)
    {
        CFHostRef host = CFHostCreateWithName(kCFAllocatorDefault, (CFStringRef)m_host);
        if (!host)
        {
            NSLog(@"Error resolving host %@", m_host);
            [NSThread sleepForTimeInterval:5.0];
            continue;
        }
        CFStreamCreatePairWithSocketToCFHost(kCFAllocatorDefault, host , m_port, &m_in, &m_out);
        CFRelease(host);

        if (!m_in)
        {
            NSLog(@"Error");
        }

        CFStreamClientContext context = {0, self,nil,nil,nil};

        if (CFReadStreamSetClient(m_in, kCFStreamEventHasBytesAvailable | kCFStreamEventErrorOccurred | kCFStreamEventEndEncountered, networkReadEvent, &context))
        {
            CFReadStreamScheduleWithRunLoop(m_in, CFRunLoopGetCurrent(),kCFRunLoopCommonModes);
        }

        if (CFWriteStreamSetClient(m_out, kCFStreamEventErrorOccurred | kCFStreamEventEndEncountered, networkWriteEvent, &context))
        {
            CFWriteStreamScheduleWithRunLoop(m_out, CFRunLoopGetCurrent(),kCFRunLoopCommonModes);
        }


        BOOL success = CFReadStreamOpen(m_in);
        CFErrorRef error = CFReadStreamCopyError(m_in);
        if (!success || (error && CFErrorGetCode(error) != 0))
        {
            NSLog(@"Connect error %s : %d", CFErrorGetDomain(error), CFErrorGetCode(error));
            [NSThread sleepForTimeInterval:5.0];
        }
        else 
        {
            NSLog(@"Connected");
            break;
        }
    }


    [self startSession];
}

- (void) startSession
{
    struct header hh;
    hh.type = RTR_CREATE_SESSION;
    hh.length = 0;
    CFIndex res = CFWriteStreamWrite(self.m_out, (const UInt8*)&hh, sizeof(hh));
    NSLog(@"Written %d", res);

    CFErrorRef error = CFWriteStreamCopyError(self.m_out);
    if (error)
    {
        NSLog(@"Read error %s : %d", CFErrorGetDomain(error), CFErrorGetCode(error));
        CFRelease(error);
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

冷︶言冷语的世界 2024-10-11 04:15:30

弄清楚了,我也忘记打开写入流:

CFWriteStreamOpen(m_out);

figured it out, I forgot to open the write stream as well:

CFWriteStreamOpen(m_out);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文