Yes, it's fine to close a stream on another thread but be aware of the consequences of doing so. If you do and another thread is using that stream, you'll get an exception. The correct thing to do is to have either an event or a wait handle that the thread doing the reading can check to see if it should shut down. The pseudocode would look something like this:
Thread 1.
pend a read operation and see if there's data to be read.
if ther's data, read some data. if not, continue
check the wait handle. If it's set, close it and terminate otherwise read some more
loop
Thread 2.
If I should trigger the network to disconnect, signal the wait handle else do whatever.
Be aware that if you're on a blocking operation, you'll get an exception. I recommend NEVER using a blocking socket, there's no reason to. We actually do (almost) all of our operations async under the hood of System.Net and the sync code paths just trigger the async code path and then block until they complete.