繁体   English   中英

GCDAsyncSocket 无法同时获取读取数据

[英]Not getting read data simultaneously GCDAsyncSocket

我这里有两个服务类。 一个是Host服务,另一个是Join服务类。 从 HostService 我发布 NetService。 在 JoinService 中,我使用 NetServiceBrowser 来获取已发布的服务。 然后成功连接到该托管服务。

HostService 和 JoinService 都包含不同的 GCDAsyncSocket 对象。 两个套接字都与主队列 ininilized 如下。

socket = GCDAsyncSocket(delegate: self, delegateQueue: .main)

当主机从 join 接受连接时,两个套接字都成功连接。 所以现在我可以互相发送数据了。

然后我从一个套接字中的任何一个发送数据。 在这里考虑从主机套接字发送。 我正在使用以下代码写入数据。 在 HostService 类中。

func sendValue(str: String) {
        let size = UInt(MemoryLayout<UInt64>.size)
        let data = Data(str.utf8)
        hostSocket.write(data, withTimeout: -1.0, tag: 0)
        hostSocket.readData(toLength: size, withTimeout: -1.0, tag: 0)
}

然后我在 sock:didWriteDataWithTag:tag 中得到调用,这是 HostService 中 GCDAsyncDelegate 的方法。

func socket(_ sock: GCDAsyncSocket, didWriteDataWithTag tag: Int) {
        let astr = "Host did write data on join port: \(sock.connectedPort)"
        print(astr)
        socketStatusCompletionBlock(astr,sock)
}

现在我希望我应该在 JoinService 的 GCDAsyncSocketDelegate 方法中实现的以下方法中同时调用。

func socket(_ sock: GCDAsyncSocket, didRead data: Data, withTag tag: Int) {
        let str = String(decoding: data, as: UTF8.self)
        let astr = "Join did read \(str) with host port: \(sock.connectedPort)"
        print(astr)
        socketStatusCompletionBlock(astr, sock)
        inComingValueCompletionBlock(str)
 }

但我不会同时接到电话。

然后,当我从与 HostService 相同的 JoinService 发送数据时,我首先在“func socket(_ sock: GCDAsyncSocket, didRead data: Data, withTag tag: Int)”中得到调用,并获得了之前从 HostService 发送的数据。

所以总而言之,当我从当前套接字写入数据时,我在 didRead 方法中获取了从另一个套接字发送的数据。

在版本中,阅读它似乎是同样的问题。 但我不明白。 GCDAsyncSocket 客户端不读取直到写入

我认为问题出在 GCDAsyncSocket.m 类中。 有功能

- (void)setupReadAndWriteSourcesForNewlyConnectedSocket:(int)socketFD{}

这是初始化这两个 dispatch_source_t 队列如下

readSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, socketFD, 0, socketQueue);

writeSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_WRITE, socketFD, 0, socketQueue);

现在按照下面的路径,打开 source.h 文件。

source.h_path_img

现在搜索dispatch_source_create

source.h_path_function

阅读函数的描述。 如下。

@function dispatch_source_create

@abstract 创建一个新的调度源来监视低级系统对象,并自动将处理程序块提交到调度队列以响应事件。

@discussion 调度源不可重入。 在调度源暂停或事件处理程序块当前正在执行时接收到的任何事件都将在调度源恢复或事件处理程序块返回后合并传递。

因此,从讨论中我可以说,当我发送时,我正在调用 readSource 的回调处理程序,但是,它合并了一段时间,并且在调度源恢复或处理程序块返回后正在交付。

现在在我的情况下,GCDAsyncReadPacket 必须初始化并通过 GCDAsyncSockets 委托方法传递,但我第一次没有得到这个 GCDAsyncReadPacket 对象。 稍后当我将调用“writeSource”的处理程序同时从与上面使用dispatch_source_create描述的行为相同的套接字写入时,它会被初始化。

所以,最后我手动初始化了 GCDAsyncReadPacket 对象,而不是稍后再获取它。 一切正常。 这是我的源代码。

https://github.com/Dhaval1094/DTSocketTicTacToe

怎么样:

- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag{
    // ... your code
    [sock readDataWithTimeout:timeout tag:tag];
}

我有同样的问题,它对我有用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM