NSStream receive NSStreamEventEndEncountered durin

2019-05-12 11:14发布

问题:

I have a client - server app that uses NSStream to connect. sometimes when trying to open a connection, one side of the connection gets NSStreamEventEndEncountered when first trying to send a message.

I use the bridge between CFStream and NSStream. My server create a socket with:

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

In the handleConnect callback function, CFStreamCreatePairWithSocketis used to get two CFStream.

My client use CFStreamCreatePairWithSocketToHost to connect to the host.

The client connects (Creates NSStreams) and then sends a ping. When my server receives a connection it opens a NSStream, and when it recieve a ping it sends a pong.

When one of the connection closes the other should get a NSStreanEventEndEncountered as I have set kCFStreamPropertyShouldCloseNativeSocket to true on the streams.

I get several different results: I used NSLog to see what was happening.

-Most of the time the connection opens and works as expected.

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

-The connection closes (NSStreamEventEndEncountered) when trying to send the pong. The client doesn't recieve the pong but recieve NSStreamEventEndEncountered

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

-The connection closes (NSStreamEventEndEncountered) when trying to send the ping. The server doesn't recieve the ping or NSStreamEventEndEncountered

Server did recieve new connection
Client closed

-An error is recieved when trying to send the ping:

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

Both the client and the server are on my computer. Why does the stream get a NSStreamEventEndEncountered when trying to write?

回答1:

I found the issue, I had a buffer that was sent as soon as my connection opened. If no data was in this buffer, an empty buffer was sent, which is an end signal for the streams.

From Apple Doc:

If the other end of the connection closes the connection:

Your connection delegate’s stream:handleEvent: method is called with streamEvent set to NSStreamEventHasBytesAvailable. When you read from that stream, you get a length of zero (0).

Your connection delegate’s stream:handleEvent: method is called with streamEvent set to NSStreamEventEndEncountered.

When either of these two events occurs, the delegate method is responsible for detecting the end-of-file condition and cleaning up.