Creating a Named Pipe sometimes fails, randomly - c#

The problem at hand is to have a "Container" app and a "Child" app communicate via a named pipe. The problem is the pipe sometimes fails to be created.
When things go smoothly, communication works pretty well.
The problem I'm seeing is that sometimes the Pipe server will fail to initialize. I can see why it happens in some instances, namely that the previous version of my app is still running in the background and did not exit properly for some reason so it's hanging on to the pipe. But, I have also seen it fail when I put in a new random name for the pipe that should not be used by any other processes, this is the part that worries me. Perhaps it is a limitation set by the OS on the same process name OR on visual studio debug mode?
To illustrate this, I have some code that tries to create a server steam (the pipe server):
NamedPipeServerStream server = new NamedPipeServerStream(pipeName, PipeDirection.InOut, 1);
The exception I often see is this:
Could not create server:System.IO.IOException: All pipe instances are busy.
I have tried a few variations of this with security options passed to the pipe + increasing the number of allowed servers from 1 to something higher but then the "Child"/Client might connect to what I assume is another process that is not properly closed out, and hence the wrong pipe server.
My ideas are:
figure out a way to "force" take over a pipe.
figure out a way to close out all dead instances of my own app somehow?
negotiate a new pipe to use writing some random pipe name to a file that both apps can read in first? This seems overkill and still not ideal if I'm having the odd behavior when I can't create a pipe even if the name is different.
Since this is hard to recreate, I am simulating the problem by doing:
var pipeName = "myApp22";
NamedPipeServerStream server = new NamedPipeServerStream(pipeName, PipeDirection.InOut, 1);
// Here I would want to catch the exception and then force close, then repeat this:
NamedPipeServerStream server = new NamedPipeServerStream(pipeName, PipeDirection.InOut, 1);
Any input would be appreciated. Thanks.

Related

Issues with WebSphere MQ + Transactions

I'm having some issues with webSphere - I am trying to run the SimpleXAGet client which basically just transactionally reads from a queue. I have a Queue on a QM running on another server and when I try to read from it, I see a connection gets open to it - but I always get an error : "CompCode: 2, Reason: 2085".
If I remove the code for the TransactionScope and no longer do them in a transaction, reads and writes work fine.
Not sure whats wrong, anyone familiar enough to take a couple guesses?

Crashed client on a named pipe server and subsequent reconnect

Evening,
I am writing this in the awareness that I am lacking a bit of fundamental understanding in named pipe server / client architecture and hope that somebody can help me. My goal is to have a server application that a client can connect to and in case the client crashes, a restart of the client application will allow for a reconnect to the server. Both applications run on the same machine.
Following scenario: I have a application/program that opens a named pipe server, like so
// Provide full access to the current user so more pipe instances can be created
PipeSecurity m_ps = new PipeSecurity();
m_ps.AddAccessRule(
new PipeAccessRule(WindowsIdentity.GetCurrent().User, PipeAccessRights.FullControl,
AccessControlType.Allow)
);
m_ps.AddAccessRule(
new PipeAccessRule(
new SecurityIdentifier(WellKnownSidType.AuthenticatedUserSid, null),
PipeAccessRights.ReadWrite, AccessControlType.Allow
)
);
/// Init the pipe
LauncherPipeServer = new NamedPipeServerStream("CommandPipe",
PipeDirection.In,
1000,
PipeTransmissionMode.Message,
PipeOptions.Asynchronous,
1,
1,
m_ps);
In a separate thread of this program I then wait for a connection from the client
...
LauncherPipeServerWorker = new System.ComponentModel.BackgroundWorker();
LauncherPipeServerWorker.DoWork += ServerPipeHandling_DoWork;
LauncherPipeServerWorker.RunWorkerAsync();
private void ServerPipeHandling_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
//...
LauncherPipeServer.WaitForConnection();
/// React to incoming messages
}
I can run this connection and it works, doing what it should. The interesting bit comes, when the application running the client crashes. Upon a restart of that application, the client is unable to reconnect to the server.
Of the solutions that I found, I wasn't really able to comprehend if and how they could solve my problem. My understanding was that the server object can accept one or multiple incoming clients and send and receive messages from all of them. So in case my client crashes, I just restart it and it can connect and register as a new client. But it doesn't seem to work that way.
Most likely an exception is thrown but yo don't see it because it's a worker thread; you have to handle it in a try/catch/finally block.
Most likely you're useing a StreamReader to read the pipe contents and then dispose of it before calling .WaitForConnection again. Disposing of a StreamReader also closes its underlying stream (unless the leaveOpen ctor parameter was true). Then the next call to .WaitForConnection will throw but it might go unnoticed, leaving the impression that the waiting has begun.

Managed WiFi error

I have been using this API ( http://managedwifi.codeplex.com/ )successfully and without any major problems. Until today at least...
I have implemented a program in C# which among others retrieves the BSSID of the connected A.P. and the number of the available wireless networks in proximity and does a number of checks. When I am connected to a certain A.P. I get a message and when I am not connected to this specific A.P. (but to another one or I am not connected at all) I get another message. Simple as that.
I did this, connection to the A.P, check once and only - when the application starts.
But...I wanted to add a timer so that this check happens every 30 or 60 seconds (and not only at the beginning). The problem is that it runs for a few times (maximum 10) and then the program freezes and I get the following message:
Win32Exception was unhandled:
An attempt was made to establish a session to a network server, but there are already too many sessions established to that server
and the message box points to WlanClient client = new WlanClient();
I don't know what is incorrect and although the code compiles correctly I get this error.
Maybe is something with the dispose of the objects?
Any help will be much appreciated.
"Maybe is something with the dispose of the objects?"
You are right, that is whats probably missing from your code.
Make
WlanClient client = new WlanClient();
a class variable and use it as often as you like.
... class Yourclass
{
private static WlanClient client = new WlanClient();
...

How to use Named Pipes without the computer hanging if no one connects to the network?

I’m looking for a way to communicate between programs on the same computer, and have been referred to Named Pipes.
It seems that the only way to connect the server is though WaitForConnection (I don’t know enough to use unmanaged code). But if no one connects to the network – the program hangs indefinitely. How do I make a connection with a timeout limit?
Thanks.
Instead of calling the synchronous WaitForConnection method, call BeginWaitForConnection/EndWaitForConnection for a non-blocking server. See here for a similar answer.
The constructor you want is the one with 5 parameters here. You can call it like so:
NamedPipeServerStream pipeServer = new NamedPipeServerStream(
"<pipe-name>",
PipeDirection.InOut,
1,
PipeTransmissionMode.Byte,
PipeOptions.Asynchronous);

client-server question

If i have a client that is connected to a server and if the server crashes, how can i determine, form my client, if the connection is off ? the idea is that if in my client's while i await to read a line from my server ( String a = sr.ReadLine(); ) and while the client is waiting to recieve that line , the server crashes , how do i close that thread that contains my while ?
Many have told me that in that while(alive) { .. } I should just change the alive value to true , but if my program is currently awaiting for a line to read, it won't get to exit the while because it will be trapped at sr.ReadLine() .
I was thinking that if i can't send a line to the server i should just close the client thread with .abort() . Any Ideas ?
Have a TimeOut parameter in ReadLine method which takes a TimeSpan value and times out after that interval if the response is not received..
public string ReadLine(TimeSpan timeout)
{
// ..your logic.
)
For an example check these SO posts -
Implementing a timeout on a function returning a value
Implement C# Generic Timeout
Is the server app your own, or something off the shelf?
If it's yours, send a "heart beat" every couple of seconds to let the clients know that the connection and service are still alive. (This is a bit more reliable than just seeing if the connection is closed since it may be possible for the connection to remain open while the server app is locked.)
That the server crashes has nothing to do with your clients. There are several external factors that can make the connection go down: The client is one of them, internet/lan problems is another one.
It doesn't matter why something fails, the server should handle it anyway. Servers going down will make your users scream ;)
Regarding multi threading, I suggest that you look at the BeginXXX/EndXXX asynchronous methods. They give you much more power and a more robust solution.
Try to avoid any strategy that relies on thread abort(). If you cannot avoid it, make sure you understand the idiom for that mechanism, which involves having a separate appdomain and catching ThreadAbortException
If the server crashes I imagine you will have more problems than just fixing a while loop. Your program may enter an unstable state for other reasons. State should not be overlooked. That being said, a nice "server timed out" message may suffice. You could take it a step further and ping, then give a slightly more advanced message "server appears to be down".

Categories

Resources