3

我有一个使用 NSStream 连接的客户端 - 服务器应用程序。有时在尝试打开连接时,连接的一侧在第一次尝试发送消息时会收到 NSStreamEventEndEncountered。

我使用 CFStream 和 NSStream 之间的桥梁。我的服务器创建一个套接字:

_ipv4cfsock = CFSocketCreate(kCFAllocatorDefault,PF_INET, SOCK_STREAM,IPPROTO_TCP, kCFSocketAcceptCallBack, handleConnect, &info);

在handleConnect 回调函数中,CFStreamCreatePairWithSocket用于获取两个CFStream。

我的客户端用于CFStreamCreatePairWithSocketToHost连接到主机。

客户端连接(创建 NSStreams)然后发送一个 ping。当我的服务器收到一个连接时,它会打开一个 NSStream,当它收到一个 ping 时它会发送一个 pong。

当一个连接关闭时,另一个应该得到一个 NSStreanEventEndEncountered,因为我kCFStreamPropertyShouldCloseNativeSocket在流上设置为 true。

我得到了几个不同的结果:我使用 NSLog 来查看发生了什么。

- 大多数情况下,连接会打开并按预期工作。

Server did recieve new connection
Server recieved ping
Server Sent pong
Client recieved pong

- 尝试发送乒乓球时连接关闭(NSStreamEventEndEncountered)。客户端没有收到 pong 但收到 NSStreamEventEndEncountered

Server did recieve new connection
Server recieved ping
Server recieved pong
Server closed
Client closed

- 尝试发送 ping 时连接关闭(NSStreamEventEndEncountered)。服务器没有收到 ping 或 NSStreamEventEndEncountered

Server did recieve new connection
Client closed

- 尝试发送 ping 时收到错误:

Server did recieve new connection;
Error recieved: The operation couldn’t be completed. Connection reset by peer

客户端和服务器都在我的电脑上。为什么流在尝试写入时会得到 NSStreamEventEndEncountered?

4

1 回答 1

7

我发现了问题,我有一个缓冲区,在我的连接打开后立即发送。如果此缓冲区中没有数据,则发送一个空缓冲区,这是流的结束信号。

来自苹果文档:

如果连接的另一端关闭连接:

您的连接委托的 stream:handleEvent: 方法在 streamEvent 设置为 NSStreamEventHasBytesAvailable 的情况下被调用。当您从该流中读取时,您会得到零 (0) 的长度。

您的连接委托的 stream:handleEvent: 方法在 streamEvent 设置为 NSStreamEventEndEncountered 的情况下被调用。

当这两个事件中的任何一个发生时,委托方法负责检测文件结束条件并进行清理。

于 2014-06-12T22:06:14.240 回答