Should EndReceive ever return zero if the socket is still connected?

Socket.EndReceive() returns 0 in one specific case: the remote host has begun or acknowledged the graceful closure sequence (e.g. for a .NET Socket-based program, calling Socket.Shutdown() with either SocketShutdown.Send or SocketShutdown.Both).

However note that technically, until the socket is finally closed, it is "connected".

You should not use the Connected property to determine whether to issue another read from the socket. Instead, since a return value of 0 is specifically reserved to indicate that no more data will be sent, you should simply check the return value of EndReceive() and call BeginReceive() again if the value is a positive number (i.e. not zero).