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?

posted on 2020-05-07 16:05  不死亡灵首席大元帅  阅读(366)  评论(0编辑  收藏  举报

导航