ios - 无法写入使用 CFStreamCreatePairWithSocket 成功创建的 CFWriteStream

标签 ios sockets stream ios-simulator

由于 iOS 开发框架中的 CFWrite/ReadStream,我在尝试建立双向异步通信时遇到了问题。

我开始创建套接字连接,一切似乎都是正确的:

CFSocketContext socketCtx = {0, self, NULL, NULL, NULL};
socket = CFSocketCreate(NULL, PF_INET, SOCK_STREAM, IPPROTO_TCP,kCFSocketConnectCallBack, (CFSocketCallBack)onConnectOrDisconnect, &socketCtx);

CFSocketEnableCallBacks(socket, kCFSocketConnectCallBack);
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_len = sizeof(addr);
addr.sin_family = AF_INET;
addr.sin_port = htons(appDelegate.portSocket);
addr.sin_addr.s_addr = inet_addr([adress cStringUsingEncoding:NSASCIIStringEncoding]);
CFDataRef connectAddr = CFDataCreate(NULL, (unsigned char *)&addr, sizeof(addr));   
CFRunLoopSourceRef sourceRef = CFSocketCreateRunLoopSource(kCFAllocatorDefault, socket, 0);
CFRunLoopAddSource(CFRunLoopGetCurrent(), sourceRef, kCFRunLoopCommonModes);
CFRelease(sourceRef);
CFSocketConnectToAddress(socket, connectAddr, -1);

然后,在我的连接回调中,我创建了两个流,一个用于读取,另一个用于写入:

void onConnectOrDisconnect(CFSocketRef socket, CFSocketCallBackType type, CFDataRef address,
                           const void *data, void *info)
{
    TCPClient * clientTCP = (TCPClient *)info;
    if(data==NULL)
    {
        [clientTCP ConnectionSuccess];
    }else {
        SInt32 *error = (SInt32*)data;
        NSLog(@"Connection error : %d", *error);
        StreamErrorOccured(clientTCP);
    }
}
- (void) ConnectionSuccess
{
    CFStreamCreatePairWithSocket(kCFAllocatorDefault, CFSocketGetNative(socket), &readStream, &writeStream);
    CFReadStreamSetProperty(readStream, kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanTrue);
    CFWriteStreamSetProperty(writeStream, kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanTrue);
    CFStreamClientContext dataStreamContext = {0, self, NULL, NULL, NULL};  
    CFOptionFlags events = kCFStreamEventHasBytesAvailable | kCFStreamEventOpenCompleted;
    if (CFReadStreamSetClient(readStream, events, readStreamEventCallBack , &dataStreamContext)) 
    {
        CFReadStreamScheduleWithRunLoop(readStream, CFRunLoopGetCurrent(), kCFRunLoopCommonModes);
    }
    if (CFWriteStreamSetClient(writeStream, kCFStreamEventOpenCompleted | kCFStreamEventCanAcceptBytes | kCFStreamEventErrorOccurred | kCFStreamEventEndEncountered,
                               writeStreamEventCallBack, &dataStreamContext))
    {
        CFWriteStreamScheduleWithRunLoop(writeStream, CFRunLoopGetCurrent(), kCFRunLoopCommonModes);
    }else {
        NSLog(@"can't create write stream client");
    }

    CFReadStreamOpen(readStream);
    CFWriteStreamOpen(writeStream);

    NSLog(@"Connection Success");
}

请注意,我在 kCFStreamEventCanAcceptBytes 事件和 kCFStreamEventOpenCompleted 事件上注册了一个回调。在此回调中,我可以看到发生了 kCFStreamEventOpenCompleted,但从未发生 kCFStreamEventCanAcceptBytes!

当我尝试在我的流上写入时,我检查了流的可用性,这要归功于:CFWriteStreamCanAcceptBytes(writeStream)。此函数始终返回 false。

如果我尝试在不调用 CFWriteStreamCanAcceptBytes 的情况下写入流,写入操作将永远循环。 我的问题是: 1. 为什么我没有收到任何 kCFStreamEventCanAcceptBytes 事件? 2. 为什么我不能在我的流上写?

我看到我的问题与:SIMILAR QUESTION 完全相同但没有人回复他。

也许我会更幸运!

干杯,

最佳答案

我不知道答案,但我也遇到了这个问题。 一种解决方案是在您的 writeStreamEventCallBack 中接收事件“kCFStreamEventCanAcceptBytes”,并在此回调函数上写入数据。 其实问题是,如果你还没有在'kCFStreamEventCanAcceptBytes'事件上发送任何数据,你下次就不能发送数据了。

A page Apple 开发文档说:

当您使用 CFStream API 进行网络连接时,套接字上的读写操作可能会阻塞。为了防止阻塞:

  1. 调用 CFReadStreamSetClient 和 CFWriteStreamSetClient 注册接收流相关的事件通知。

  2. 调用 CFReadStreamScheduleWithRunLoop 和 CFWriteStreamScheduleWithRunLoop 以在运行循环上安排流以接收与流相关的事件通知。

  3. 调用 CFReadStreamOpen 和 CFWriteStreamOpen 打开每个流。

  4. 仅在收到 kCFStreamEventHasBytesAvailable 通知后才读。仅在收到 kCFStreamEventCanAcceptBytes 通知后写入。

关于ios - 无法写入使用 CFStreamCreatePairWithSocket 成功创建的 CFWriteStream,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9571411/

相关文章:

iOS 将我们自己的位置分享给其他人?

ios - 为什么 Collection View 不重新加载?

java - Java 可以阻止开放 TCP 端口吗?

html - 如何在html5中绘制音频流的波形?

c# - 写入没有文件路径的流

ios - UIWebview - 无法打开受密码保护的 .xlsx、.docx 和 .ppt

ios - 使 CCSprite 在触摸时跟随另一个 CCSprite?

java - Bufferedreader 永远不会为空,while 循环不会终止

Python,为什么在使用 TCP 套接字时出现错误 10035(在服务器上)和 10053(在客户端上)?

javascript - 在 NodeJS 中写入文件时内存不足