试图在OS X中的套接字上打开写入流

时间:2016-01-02 04:10:29

标签: c++ macos sockets network-programming asyncsocket

在网上阅读了很多例子之后,我尝试编写一个简短的简单程序来测试两台计算机之间的套接字连接。我有这两台电脑

我从一个更简单的同步设计开始,但在没有工作时转移到runloop / async。

症状:CFWriteStreamOpen返回true(成功),但流无限期地保持在kCFStreamStatusOpening状态。永远不会调用回调来确认open是否完成(事实上它永远不会被调用任何事件)。

我怀疑我可能会遇到可能阻止此连接的网络问题(防火墙等)。为了反驳这个理论,我在客户端也运行http://sockettest.sourceforge.net/,客户端和服务器连接正常。

#include <iostream>
#include <CoreFoundation/CFStream.h>
using namespace std;

CFStreamClientContext myContext = {0,NULL,NULL,NULL,NULL};

#define SA_HOST "192.168.0.118"
//#define SA_HOST "127.0.0.1"
#define SA_PORT 6237
UInt8 buf[5] = { 0, 1, 2, 3, 4 };
UInt8 *wp = buf;
UInt16 bytesQueued = 5;
UInt16 bytesSent = 0;

static const CFOptionFlags kWriteStreamEvents =
kCFStreamEventEndEncountered |
kCFStreamEventErrorOccurred |
kCFStreamEventCanAcceptBytes |
kCFStreamEventOpenCompleted |
kCFStreamEventNone;

void WriteStreamCB(CFWriteStreamRef writeStream, CFStreamEventType event, void *clientCallBackInfo)
{
    switch (event)
    {
        case kCFStreamEventEndEncountered:
        {
            cout << "in CallBack: kCFStreamEventEndEncounteredd" << endl;
            CFWriteStreamClose(writeStream);
            break;
        }
        case kCFStreamEventErrorOccurred:
        {
            cout << "in CallBack: kCFStreamEventErrorOccurred" << endl;
            CFStreamError err = CFWriteStreamGetError(writeStream);
            cout << "in Callback: stream error, domain: " << err.domain << ", value: " << err.error << endl;
            break;
        }
        case kCFStreamEventCanAcceptBytes:
        {
            cout << "in CallBack: kCFStreamEventCanAcceptBytes" << endl;

            bytesSent = CFWriteStreamWrite(writeStream, buf, 5);
            if (bytesSent > 0)
            {
                bytesQueued -= bytesSent;
                wp += bytesSent;
                cout << "CFWriteStreamWrite wrote " << bytesSent << " bytes, " << bytesQueued << " left" << endl;
            }
            else
            {
                cout << "CFWriteStreamWrite returned " << bytesSent << endl;
            }
            break;
        }
        case kCFStreamEventNone:
        {
            cout << "in CallBack: kCFStreamEventNone" << endl;
            break;
        }
        case kCFStreamEventOpenCompleted:
        {
            cout << "in CallBack: kCFStreamEventNone" << endl;
            break;
        }
    }
}

int main(int argc, const char * argv[]) {
    CFWriteStreamRef   writeStream;
    CFStringRef host = CFSTR(SA_HOST);
    UInt32 port = SA_PORT;

    CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, host, port, NULL, &writeStream);
    CFWriteStreamSetClient(writeStream, kWriteStreamEvents, WriteStreamCB, &myContext);
    CFWriteStreamScheduleWithRunLoop(writeStream, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);

    if (!CFWriteStreamOpen(writeStream))
    {
        return -1;
    }

    while (true);

    return 0;
}

1 个答案:

答案 0 :(得分:0)

您不允许runloop运行。

〜p>〜3天后,我遇到了这个问题,终于发现CFRunLoopRun()必须称为AFTER CFWriteStreamOpen。没有记录在任何地方。为那些以后搜索并找到它的人加油

引用注释以提高知名度。关键是,如果您的CF套接字代码已挂起,则可能需要运行您的运行循环。

此外,如果您没有执行基于运行循环和基于回调的API使用模式,即如果您正在使用CFWriteStreamWrite阻止IO且未设置“流客户端”,则由于超时等错误。