• 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 FilesIBMMQToolsdotnetsamples 中就能找到示例源码。

    我使用的是C:Program FilesIBMMQToolsdotnetsamplescsxmssimplewpmSimpleConsumer。

    问题分析:

    这是一个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 FilesIBMMQin。

    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?

  • 相关阅读:
    Heartbeat+Haproxy实现负载均衡高可用
    Heartbeat+Haproxy实现负载均衡高可用
    Heartbeat+Haproxy实现负载均衡高可用
    Heartbeat+Haproxy实现负载均衡高可用
    apache调优技巧之一隐藏apahce版本信息
    apache调优技巧之一隐藏apahce版本信息
    apache调优技巧之一隐藏apahce版本信息
    apache调优技巧之一隐藏apahce版本信息
    用VC实现洪水攻击程序
    WebAPI返回数据类型解惑 以及怎样解决Extjs无法解析返回的xml
  • 原文地址:https://www.cnblogs.com/nevermore-wd/p/12843646.html
Copyright © 2020-2023  润新知