NamedPipeClientStream - no way to cancel Connect - c#

I'd like to use NamedPipeClientStream:
var _Pipe = new NamedPipeClientStream(".", "test-a", PipeDirection.In);
_Pipe.Connect();
Unfortunately, there is no way to pass Cancellation token. So, how to cancel connection? I don't want to pass timeout - my client needs to wait "forever" until connection is successful or cancel is requested. ConnectAsyncis not available.
EDIT:
I am using .NET Frameowkr 4.5.2 Class library, and there is no such a method like ConnectAsync (only Connect is available).

To cancel, call Close() or Dispose() method on that pipe. If you'll need to retry later, just create another pipe for that.
I’m 90% sure the thread that was sleeping on that Connect() call will wake up immediately, and fail with some exception. Probably ObjectDisposedException if you call Dispose, or some "The pipe is being closed." Win32 exception if you call Close().
I have never tested with pipes specifically, but that’s what usually happens in Windows with blocking I/O calls for files and sockets.

Related

How do I close all connections to my server? [duplicate]

On the server side, I'm trying to gracefully close a connected socket. I know the proper sequence of events on the Socket should be:
socket Shutdown with the SocketShutdown.Send option
loop/wait until a socket Receive returns with 0 bytes
socket Close
I have a few questions:
what if Socket.Receive never returns (with 0 bytes)? will we be stuck trying to close the socket forever?
whenever i call Close on the server, the Client always receives "an existing connection was forcibly closed by a remote host" exception on their end. how can i have the client notified of this close "gracefully"?
on the server, if I'm using Async Begin/EndReceive calls, whenever I call Close on the socket, it ALWAYS results in an ObjectDisposedException on the Begin/EndReceive thread. Is there no way to Close a socket without this exception from occurring?
The TCP protocol guarantees the socket will close eventually unless the peer refuses to allow it to close. In which case, you should wait forever or give up, whatever's appropriate.
If you close the socket after receive returns zero, that should not happen. If it is, your code is likely doing something wrong.
You can't release a resource while an asynchronous operation is or might be using it. Rather than calling close, call shutdown. Don't call close until you're 100% finished with the resource.

I'm using Socket to listen for new connections. How do I break out of synchronous Socket.Accept() method? How do I terminate this call?

I understand, Socket.Accept() is a blocking call, and there is no timeout property for it (like ReceiveTimeout or SendTimeout). So the thread will just keep waiting indefinitely for a new connection to arrive.
So my questions is, how do I terminate this call after a certain point of time. Should I consider closing the listening Socket from some other thread?
Any better ways to do this?
You could use Socket.Poll which allows you to wait for a connection with a timeout. Call it with SelectMode.SelectRead, and if it returns true there is a connection pending that you can accept without blocking.

Way to check if NamedPipeServerStream started in Client side

I have a client using NamedPipeClientStream and a server using NamedPipeServerStream.
The client may start before the server, and when it call clientStream.Connect(timeout) i get TimeoutException as expected.
Is there any way I can check if there is a NamedPipeServerStream listening before calling the Connect to prevent an exception?
If someone bumps into this question five years later, this might be helpful:
var isPipeRunning = Directory.GetFiles( #"\\.\pipe\" ).Contains( $"\\.\pipe\{pipeName}" )
I suggest you should use an EventWaitHandle. On all clients, call WaitOne () and on server after opening the stream, call Set ().
So, on "server" side, write this:
EventWaitHandle handle = new EventWaitHandle(false, EventResetMode.ManualReset, String.Format(#"Global\{0}", "SERVER_OPENED_HANDLE"));
OpenStream (); // inside this method you would have code that opens your named pipe for incomming messages
// finally, signal that you are done
handle.Set ();
On client side, write something like this:
EventWaitHandle handle = new EventWaitHandle(false, EventResetMode.ManualReset, String.Format(#"Global\{0}", "SERVER_OPENED_HANDLE"));
// here your thread will sleep until the server calls "Set"
handle.WaitOne ();
// then you can safelly connect to the server here
ConnectToServer ();
There remains just a few situations to handle:
1) The pipe can't be opened on server becase there is already an opened pipe with the same name (will throw an exception).
2) You successfully opened the pipe, you notified clients that you are ready but after that, a milisecond after, the server crushes from some unexpected reason and the client cannot reach the server.
3) User rights problems
In all these situations, you should handle these exceptions using a try / catch and normally, if all goes well, this code will ensure that the client will NOT try to connect before the server successfully opened the pipe.
Anyway, I suggest using a more advanced technique for making IPC through Named Pipes such as using WCF or even .NET Remoting wich besides the fact that it's somehow considered obsolete by many (don't include me) is very decent at least for IPC communication. This will give you the freedom and scalability (maybe one day you will need your clients to be able to reside on other machines, and you will have to switch from IPC to a LAN communication or even in WAN / internet).
There is no way to check this only using a NamedPipeClientStream. However, you can use a Mutex like so
// In the server
var mutex = new System.Threading.Mutex(false, "MyPipeMutex");
OpenPipeAndRunServer();
mutex.Close();
// In the client process
var mutex = new System.Threading.Mutex(false, "MyPipeMutex");
if (!mutex.WaitOne(0, false))
{
OpenPipe();
}
mutex.Close();
You will probably want to wrap the Close calls in a try-finally block to make sure it always closes. In the client you can use a different timeout to actually wait for the NamedPipe to be opened.
You can also catch the exception as a work around.

Exiting a thread blocking on TCP read in C#

My server/client start a new thread "readerThread()" for reading incoming tcp traffic. This thread blocks on read(). How can i exit this readerThread().
One way is to start another thread which closes the socket when the thread is to be exited so the read would exit. is there a more cleaner/better way to do it.
I misunderstood the question. Here is what I think you should do.
If you created the socket in parent thread, and only use the new thread to read incoming data, then I would suggest calling Socket.Shutdown().This way the Receive methods will return 0 (no bytes read), and you can exit from thread's method. Shutdown will disable send/receive, but if there is any data in buffer that is waiting to be sent/received it will ensure that it is sent/received before closing the socket. Your Receive method will return 0 if you call shutdown while the socket is blocked on Receive, but it will throw a socket exception with Socket error code = Shutdown (or 10058). So be ready to catch and handle it.
If you create the socket in new thread, and its accepting new connections (Socket.Listen() and Socket.Accept) then you can connect with that socket from your parent thread and Send 0 bytes. You can exit new thread when Receive methods returns 0 bytes.
If you are creating the socket in new thread, and it can only a client (Connects with other socket) then this is not a good approach at all. You may have to Abort the thread (not recommended), unless you configure your server to send 0 bytes when you want your client socket to close, but this way your client app will be dependent on server for closing the socket.
If you're using a blocking read() command, you should almost always have another control thread that is in charge of shutting it down and cleaning up the socket.
Typically though, I would use a select() call that times out after 1 second or so to test if there is data to be read, and each timeout cycle checks if a shutdown status flag has been set by another thread.
But if you go with pure blocking, use a control thread as you suggest.
I would use Asnyncronous Socket communication. I wrote an article which demos this on my blog. ou can read here:
http://www.andrewrea.co.uk/blog/2009/06/09/Part1SocketProgrammingWithCJAVACAndActionScript30EstablishingABaseConnectionAndCommunicationWithCServerAndAS3.aspx
Andrew
I'm somewhat puzzled what exactly you are doing: there is no read() method for the Socket class in .NET.
My recommendation is to create a second socket, which is listening on a specific port, and have the thread block in Socket.Select instead. Connecting to that second socket should be taken as a shutdown request (perhaps after proper authentication, e.g. by sending an application password over that socket).
Another way to do it is to send a 0 byte packet to your listening socket from somewhere else in your own application when you want to shut it down.
I've found that's a slightly cleaner approach than closing the coket from another thread since an exception will be thrown by the listening thread if you close the socket on it.

c#/.Net Socket.Shutdown

I recognize this type of question has a long history, but the way I am using this must be the correct '.net way' and yet it does not seem to work.
I have a trivial synchronous IP server daemon that does a simple AcceptSocket, do some stuff, socket.send, socket.shutdown, socket.close. My client is another trivial C# app that does URLDownloadToFile.
What happens is that part of the time URLDownloadToFilefails fails with (0x800C0008) .. thinks its download resource failed.
My server side end sequence is:
socket.Shutdown(Both);
socket.Close();
If I change this to
socket.Disconnect();
socket.Close();
(I open the above with sockopt Linger true, timeout 5 secs)
this works great.
Am I missing something on the Shutdown method.. it sounds like the 'magic bullet' MS wants you to use for gracefully doing an exit that will ultimately send any remaining send data.
Grossly, (and this cannot be right) it appears like the close.. kills any async processing that might be in progress from shutdown().
Any ideas?
Based on Socket.Disconnect
If you need to call Disconnect without first calling Shutdown, you
can set the DontLinger Socket option
to false and specify a nonzero
time-out interval to ensure that data
queued for outgoing transmission is
sent. Disconnect then blocks until the
data is sent or until the specified
time-out expires. If you set
DontLinger to false and specify a zero
time-out interval, Close releases the
connection and automatically discards
outgoing queued data.
Suggests the Shutdown is at best unnecessary...
For reusing the socket use:
socket.Shutdown(SocketShutdown.Both);
socket.Disconnect(true);
For force closing use:
socket.Shutdown(SocketShutdown.Both);
socket.Close();

Categories