没有同时读取数据GCDAsyncSocket

Posted

技术标签:

【中文标题】没有同时读取数据GCDAsyncSocket【英文标题】:Not getting read data simultaneously GCDAsyncSocket 【发布时间】:2019-12-21 13:36:30 【问题描述】:

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

HostService 和 JoinService 都包含不同的 GCDAsyncSocket 对象。两个套接字都被主队列初始化,如下所示。

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

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

然后我从任何一个套接字发送数据。考虑在这里从主机套接字发送。我正在使用以下代码写入数据。在 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 Client not reading until write

【问题讨论】:

【参考方案1】:

我认为问题出在 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文件。

现在搜索 dispatch_source_create

从函数中读取描述。如下。

@function dispatch_source_create

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

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

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

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

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

https://github.com/Dhaval1094/DTSocketTicTacToe

【讨论】:

【参考方案2】:

怎么样:

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

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

【讨论】:

以上是关于没有同时读取数据GCDAsyncSocket的主要内容,如果未能解决你的问题,请参考以下文章

在 iOS 中通过 GCDAsyncsocket 读取 xml 文件

同时读取两个文件进行while循环

有没有办法强制所有列成为字符串,同时从.csv文件读取数据到DataTable?

java 中简述使用流进行读写文本文件的步骤?

读取数据问题同时更新和/或写入 Postgres DB

如何提高报表的取数性能