C#与JMS的连接问题
问题描述:
编译IBM提供的sample代码,并运行。实现与目标JMS(java message server)主机的通信。但是在连接Topic的时候发生了异常。
异常代码:红色字体
XMSFactoryFactory factoryFactory; IConnectionFactory cf; IConnection connectionWPM; ISession sessionWPM; IDestination destination; IMessageConsumer consumer; ITextMessage textMessage; // Get an instance of factory. factoryFactory = XMSFactoryFactory.GetInstance(XMSC.CT_WPM); // Create WPM Connection Factory. cf = factoryFactory.CreateConnectionFactory(); // Set the properties cf.SetStringProperty(XMSC.WPM_BUS_NAME, busName); cf.SetStringProperty(XMSC.WPM_PROVIDER_ENDPOINTS, endPoint); cf.SetStringProperty(XMSC.WPM_TARGET_TRANSPORT_CHAIN, transportChain); // Create connection. connectionWPM = cf.CreateConnection(); Console.WriteLine("Connection created"); // Create session sessionWPM = connectionWPM.CreateSession(false, AcknowledgeMode.AutoAcknowledge); Console.WriteLine("Session created");
异常内容:我给转成了json格式
{ "NativeErrorCode": 11004, "ClassName": "System.Net.Sockets.SocketException", "Message": "The requested name is valid, but no data of the requested type was found", "Data": null, "InnerException": null, "HelpURL": null, "StackTraceString": "at IBM.XMS.Util.InternetProtocol.GetIPAddress(String address) at IBM.XMS.SIB.Trm.TrmSICoreConnectionFactoryImpl.Attach(Credentials credentials,SICoreConnectionProperties connectionProperties,ClientAttachProperties cap) at IBM.XMS.SIB.Trm.TrmSICoreConnectionFactoryImpl.Bootstrap(Credentials credentials,SICoreConnectionProperties connectionProperties,ClientAttachProperties cap) at IBM.XMS.SIB.Trm.TrmSICoreConnectionFactoryImpl.CreateConnection(Credentials credentials,SICoreConnectionProperties connectionProperties) at IBM.XMS.SIB.Trm.TrmSICoreConnectionFactory.CreateConnection(String username, String password, SICoreConnectionProperties connectionProperties) at IBM.XMS.Impl.ConnectionFactory.CreateConnection(String userName, String password)", "RemoteStackTraceString": null, "RemoteStackIndex": 0, "ExceptionMethod": "8 GetIPAddress IBM.XMS.Util, Version=9.0.0.4, Culture=neutral, PublicKeyToken=d2666ab12fca862b IBM.XMS.Util.InternetProtocol System.Net.IPAddress GetIPAddress(System.String)", "HResult": -2147467259, "Source": "IBM.XMS.Util", "WatsonBuckets": null }
!有的client会报这个异常,有的就不会。
Note:刚接触JMS的人可以去IBM官网下载IBM MQ Client。安装后,在C:\Program Files\IBM\MQ\Tools\dotnet\samples 中就能找到示例源码。
我使用的是C:\Program Files\IBM\MQ\Tools\dotnet\samples\cs\xms\simple\wpm\SimpleConsumer。
问题分析:
这是一个socket异常。搜索socketexception 11004,几乎所有的解决方法都是确认网络连接。 可是目标主机的ip可以ping通,port可以telnet成功。
Note:C#连接JMS一共需要四个参数:endpoint(ip+port);busname;transportchain;topicName/queueName。
抛异常的方法是CreateConnection() ,那就确认和topicName/queueName无关。其他三项和同事反复确认都没问题。
最重要的是:有的client OK 有的就NOK。一样的程序,不一样的只有PC了。根据这一点很容易就想到是否有未安装IBM MQ Client的情况。
经过确认,所有的PC都安装了相同版本的IBM MQ Client。而且如果未安装IBM MQ Client,那报错的方法应该是CreateConnectionFactory(),而不是CreateConnetion()。
至此,我认为client端的所有可能性都已经排除。由于存在连接成功的client端,所以也可以排除server端的问题。
那就剩下网络问题了,我第一个想到的是防火墙。可是出异常的那几台PC都是可以访问目标IP和Port的。
再回到异常的方法
IBM.XMS.Util.InternetProtocol.GetIPAddress(String address)
通过反射工具找到GetIPAddress()。Note:反射的程序集是IBM.XMS.Until。位于C:\Program Files\IBM\MQ\bin。
namespace IBM.XMS.Util { // Token: 0x0200002D RID: 45 public sealed class InternetProtocol { // Token: 0x06000213 RID: 531 RVA: 0x0000B6BC File Offset: 0x0000A6BC private InternetProtocol() { } // Token: 0x06000214 RID: 532 RVA: 0x0000B6C4 File Offset: 0x0000A6C4 public static IPAddress GetIPAddress(string address) { IPAddress result = null; try { try { result = IPAddress.Parse(address); } catch (Exception) { IPHostEntry iphostEntry = null; try { iphostEntry = Dns.GetHostEntry(address); } catch (Exception ex) { throw ex; } if (iphostEntry == null || iphostEntry.AddressList.Length <= 0) { throw new Exception(); } result = iphostEntry.AddressList[0]; } } catch (Exception ex2) { throw ex2; } return result; } } }
通过这段代码,不难看出能抛出socket异常的产生过程
result = IPAddress.Parse(address);->throw->iphostEntry = Dns.GetHostEntry(address);->throw
这段代码是干什么的呢?为什么要解析本机IP?应该只有IBM.XMS的开发者才知道了。 现在可以确认的是PC的ip需要查一下。经过查看,发生异常的PC使用的都是静态IP。没有异常的PC都是用的动态获取IP......
问题解决:
将发生异常的PC由静态IP改成自动获取。重新测试,连接成功!
难道JMS client不支持静态IP?