0

我正在 ios 上编写一个公告板系统 (BBS) 阅读器。我使用 GCDAsyncSocket 库来处理数据包的发送和接收。我遇到的问题是服务器总是将要发送的数据拆分为多个数据包。我可以通过在 didReceiveData() 函数中打印出接收字符串来看到这种情况。

从 GCDAsyncSocket 自述文件中,我了解 TCP 是一个流。我也知道有一些流结束机制,例如末尾的双 CR LF。我已经使用 WireShark 解析数据包,但在最后一个数据包中没有某种模式的迹象。该站点不归我所有,因此我无法发送某些字节。一定有办法检测最后一个数据包,否则BBS客户端如何处理显示数据?

4

1 回答 1

0

双 CR LF 不是流的结尾。例如,这只是 HTTP 协议细节的一部分,但与关闭流无关。HTTP 1.1 允许我在单个流上发送多个响应,在 HTTP 标头后使用双 CR LF,没有流结束。

当从另一端关闭时,TCP 套接字流将在读取时返回 0,阻塞或非阻塞。

因此,假设服务器在完成发送给您后将关闭套接字,您可以循环并执行阻塞读取,如果返回 > 0,则处理数据,然后再次读取。if < 0,处理错误码(可能是致命的也可能不是),如果== 0,socket从另一端关闭,不再读取。

对于非阻塞套接字,您可以使用 select() 或其他一些 API 来检测流何时准备好读取。我不熟悉您正在使用的特定库,但如果它是 POSIX / Berkeley 套接字 API,它将以这种方式工作。

无论哪种情况,您都应该构建一个输入缓冲区,将每次读取的结果连接起来,直到您准备好处理。正如您所发现的,您不能假设单次读取将返回完整的应用程序级数据包。但是关于你的问题,除非服务器要你关闭套接字,否则你应该等待读取返回 0。

于 2014-06-18T23:29:38.887 回答