I am trying to connect to an existing JMS queue with a .NET client.
I know the queue is working, I already browsed it using IBM MQ Explorer.
In the following code, the call to factory.CreateConnection keeps hanging - it does not jump to the next line, in does not show any error message. It even doesnt consume any CPU.
Are there any options that I should try to get it working (or at least make it show me an error message of any kind)?
private static IConnectionFactory GetConnectionFactory()
{
var factoryFactory = XMSFactoryFactory.GetInstance(XMSC.CT_WMQ);
var cf = factoryFactory.CreateConnectionFactory();
cf.SetStringProperty(XMSC.WMQ_HOST_NAME, "server address");
cf.SetIntProperty(XMSC.WMQ_PORT, portnumber);
cf.SetStringProperty(XMSC.WMQ_CHANNEL, "channelname");
cf.SetIntProperty(XMSC.WMQ_CONNECTION_MODE, XMSC.WMQ_CM_CLIENT);
cf.SetStringProperty(XMSC.WMQ_QUEUE_MANAGER, "queuemanager");
cf.SetIntProperty(XMSC.WMQ_BROKER_VERSION, XMSC.WMQ_BROKER_UNSPECIFIED);
return (cf);
}
The main method has the following:
var factory = GetConnectionFactory();
var connection = factory.CreateConnection("username", null);
I don't see any problem with your code, tested it with MQ v8 and works fine. I would suggest you to do:
1) XMS can run in unmanaged mode also. So change
cf.SetIntProperty(XMSC.WMQ_CONNECTION_MODE, XMSC.WMQ_CM_CLIENT);
to
cf.SetIntProperty(XMSC.WMQ_CONNECTION_MODE, XMSC.WMQ_CM_CLIENT_UNMANAGED)
and see if that helps.
2) When the call hangs, break into debug and see the call stack to determine the point of hang. It could be waiting on some system event if no CPU is being consumed.
3) Open a PMR with IBM.
Related
I am trying to make a single application that is both a Client and Server using SignalR in .NET. The end goal is to integrate it with our existing product, which requires to be both a client and server as one computer acts as both, while the other computers are all clients.
Full source code on GitHub.
In the Client startup code, which is run after the Server startup code has completed, the following code is run:
m_hubConnection = new HubConnection( "http://localhost:8080/" );
m_myHubProxy = m_hubConnection.CreateHubProxy( nameof( ServerHub ) );
m_myHubProxy.On<string, string>( nameof( ServerHub.BroadCastMessage ), ( name, message ) => OnMessageReceived( name, message ) );
m_hubConnection.Closed += OnClosed;
m_hubConnection.Error += OnErrorReceived;
await m_hubConnection.Start(new WebSocketTransport());
await SendMessage( "Startup", "Sending from same thread as connection established" );
The OnClosed callback is called almost right away, so the connection closes immediately upon starting.
The OnErrorReceived callback is never called, so it does not close due to any obvious error
The Start method hangs and never calls back
The SendMessage method is never hit
Ideally, I want the connection to open, stay open, have that SendMessage be hit, send a message to the Hub, and have that broadcast the same message back to the client.
Any ideas on what's going wrong?
Fixed it, insanely silly mistake. I just switched from port 8080 to 8089. I guess something else is using port 8080, but regardless, switching both the client and server side to port 8089 fixed it.
I've tried checking the server:port with telnet and I'm getting the expected results. So either writer.Write() or reader.ReadLine() isn't working cause I get nothing from the server.
TcpClient socket = new TcpClient(hostname, port);
if (!socket.Connected) {
Console.WriteLine("Failed to connect!");
return;
}
TextReader reader = new StreamReader(socket.GetStream());
TextWriter writer = new StreamWriter(socket.GetStream());
writer.Write("PING");
writer.Flush();
String line = null;
while ((line = reader.ReadLine()) != null) {
Console.WriteLine(line);
}
Console.WriteLine("done");
EDIT: I might have found the issue. This code was based off examples I found on the web. I tried another irc server: open.ircnet.net:6669 and I got a response:
:openirc.snt.utwente.nl 020 * :Please wait while we process your connection.
It seems as if I probably need to run the reader in a Thread so it can just constantly wait for a response. However it does seem weird that the program got caught on the while loop without ever printing done to the console.
I think you need to provide further details. I'm just going to assume that because you can easily telnet to the server using the same port your problem lies in the evaluation of the Connected property...
if (!socket.Connected) {
Console.WriteLine("Failed to connect!");
return;
}
this is wrong because Microsoft clearly specifies in the documentation that the Connected property is not reliable
Because the Connected property only reflects the state of the connection as of the most recent operation, you should attempt to send or receive a message to determine the current state. After the message send fails, this property no longer returns true. Note that this behavior is by design. You cannot reliably test the state of the connection because, in the time between the test and a send/receive, the connection could have been lost. Your code should assume the socket is connected, and gracefully handle failed transmissions.
That said, you should not use this property to determine the state of the connection. Needless to say that using this property to control the flow of your console app will result in unexpected results.
Suggestion
Remove the evaluation of the Connected property
Wrap your GetStream and Write method calls in a try/catch block to handle network communication errors
reader.ReadLine() will just wait for any data to arrive. If no data arrive, it seems to hang. That's a feature of tcp (I don't like it either). You need to find out how the end of the message is defined and stop based on that end criterion. Be careful, the end of message identifier may be split into two or more lines...
RFC for ping says that the server may not respond to it & such connections has to be closed after a time. Please check the RFC: https://www.rfc-editor.org/rfc/rfc1459#section-4.6.2
I'm building an application that uses Named Pipes for IPC.
When started writing a stress test, I found an issue related to when a client does quickly connect-disconnect.
Server code:
static void ServerThread()
{
var serverPipe = new NamedPipeServerStream("myipc", PipeDirection.InOut, -1, PipeTransmissionMode.Message, PipeOptions.Asynchronous | PipeOptions.WriteThrough);
serverPipe.BeginWaitForConnection(
ar =>
{
var thisPipe = (NamedPipeServerStream)ar.AsyncState;
thisPipe.EndWaitForConnection(ar);
Task.Factory.StartNew(ServerThread);
thisPipe.Dispose();
},
serverPipe);
}
Client does nothing but connect-disconnect as follow:
static void RunClients()
{
for (int i = 0; i < 100; i++)
{
var clientPipe = new NamedPipeClientStream(".", "myipc", PipeDirection.InOut, PipeOptions.Asynchronous | PipeOptions.WriteThrough);
clientPipe.Connect(1000);
clientPipe.Dispose();
}
}
When this runs, one of the clients is failing in Connect() while the server fails in BeginWaitForConnection - saying Pipe is being closed.
If I add at least Thread.Sleep(100) before each client disposes - everything works just fine.
I'm sure what I'm doing is a corner case, but I believe the pipes should be able to handle this in greaceful way.
Any ideas on what could be wrong?
Thanks!
one of the clients is failing in Connect()
Because the server immediately disposes the pipe after connecting.
the server fails in BeginWaitForConnection
Because the client immediately disposes the pipe after connecting.
I believe the pipes should be able to handle this in greaceful way.
It does, it gracefully throws an exception to let your code know that something exceptional happened. You seem to assume it is normal that code closes a pipe without doing anything to let the other end know that the pipe is about to disappear. That is not normal, it is exceptional. So you get an exceptional notification for it.
You catch exceptions with try/catch. There are two things you can do in your catch handler. You can assume that it is okay for code to close a pipe willy-nilly, in which case you do nothing beyond closing your end of the pipe and get out. Or you can assume that something Really Bad happened because the other end of the pipe didn't say goodbye nicely. Which is rather important to distinguish the oh-crap kind of mishaps, like a pipe client or the server crashing. It is up to you to choose your preferred way, but I strongly recommend to not ignore the oh-crap scenarios, it does and will happen. You just created a good simulation of such a mishap.
So I've been getting this exception for about a week now, and I've finally managed to corner it into a code snippet that can be easily read.
As a background, I am programming an app for Windows RT and I am trying to use basic sockets.
For the sake of testing, I've created a local socket listener to act as a server. Both the server and client need to be able to read/write on the socket.
Neither the client nor the server can (or should) know how much data will come across the wire (if any). This is an absolute requirement. The server should be able to process an arbitrary amount of data on demand.
Here is an example. It is presented as a Unit Test, simply because that is where I consistently encounter the error. Removing any single line from this example causes the error to go away:
[TestMethod]
public async Task TestSomething()
{
// Setup local server
//
StreamSocketListener listener = new StreamSocketListener();
listener.ConnectionReceived += async (sender, args) =>
{
DataReader serverReader = new DataReader(args.Socket.InputStream);
await serverReader.LoadAsync(4096); // <-- Exception on this line
};
await listener.BindServiceNameAsync("10181");
// Setup client
//
using (StreamSocket socket = new StreamSocket())
{
await socket.ConnectAsync(new HostName("localhost"), "10181");
DataReader reader = new DataReader(socket.InputStream);
Task readTask = Listen(reader);
}
}
public async Task Listen(DataReader reader)
{
await reader.LoadAsync(4096);
}
The exception happens on the line where the server calls LoadAsync(...), and the exception is thrown when the unit test quits.
The exception is (seemingly) simple:
An existing connection was forcibly closed by the remote host.
(Exception from HRESULT: 0x80072746)
Any clues would be greatly appreciated.
With the new WinRT socket types, it's easier than ever to program sockets correctly, but make no mistake: they are still complex beasts.
The "forcibly closed" (WSAECONNRESET / 10054) error is when the remote side (in this case, the client) aborts its connection, which it does by disposing its StreamSocket. This is reported as an error but is not uncommon and should be handled gracefully. I.e., if the server has sent all its data and is just waiting to receive more (optional) data, then it should treat WSAECONNRESET as a regular close.
Tip: If you pass Exception.HResult to SocketError.GetStatus, you should see it's SocketErrorStatus.ConnectionResetByPeer. That way you can avoid magic values in your error handling code.
P.S. I have a blog post describing some of the more common socket errors and socket error handling in general.
This question is related to my earlier question.
Connecting to the pipe is now successful, but I still cannot read (or write) any data from the port.
My first guess was, that the data are buffered. But even when I write (on the client site) 5000 bytes (the buffer in NamedPipeClientStream is 512 byte large), I do not receive any
data.
PipeOptions.WriteThrough didn't changed anything, too.
When I do not use a pipe, but a textfile (in the Virtual-PC settings) to redirect the data written to the COM-Port, the data are written as expected to the textfile. So the client test programm, running in Virtual-PC, is doing fine. The problem is likely in my code below.
var pipe = new NamedPipeClientStream(".", "mypipe", PipeDirection.InOut, PipeOptions.WriteThrough);
pipe.Connect();
// this is blocking
int i = pipe.ReadByte();
var reader = new StreamReader(pipe);
// this is blocking, too
var s = reader.ReadLine();
Update:
The code I am running on the guest os:
var port = new SerialPort("COM1");
port.Open();
port.WriteLine("Hallo");
Using 'echo' in an command prompt as telewin suggested works fine.
What is the difference between echoing and using the above code?
Sorry for the late reply, hope it's still relevant...
In my tests, "echo hello > com1" only works before you run your program (which initiates a new SerialPort) inside VPC. After you run it, "echo hello > com1" will no longer be seen by the host program, until the guest is rebooted.
This suggests that the initialization of the SerialPort itself does something permanent. Using Reflector we find that SerialPort's ctor does nothing of consequence, but its Open method calls the ctor for SerialStream. This ctor does quite a bit: it sets read/write buffers, Rts/Dtr, and handshake mode. After some trials, it seems that the Rts/Dtr screw up the "echo hello > com1". Can you please try this modified code inside VPC:
var port = new SerialPort("com1");
port.DtrEnable = true;
port.RtsEnable = true;
port.Open();
port.WriteLine("Hallo");