msmq 之端口开放问题

项目中需要用java访问远端的msmq,从网上找了一个开源的实现:

http://msmqjava.codeplex.com

使用上一波三折,经过分析验证,打开队列采用不同的AccessMode,会决定访问远端的不同接口,佩服微软提供的API,竟然有如此威力。

 

现记录下分析的主要内容,以备查找。

 

MSMQ端口

http://support2.microsoft.com/kb/178517

 

Opening Queues

http://msdn.microsoft.com/en-us/library/ms706937(v=vs.85).aspx

 

Opening Remote Queues with Send Access

http://msdn.microsoft.com/en-us/library/ms705186(v=vs.85).aspx

 
msmq 之端口开放问题_第1张图片
  

此时采用的端口根据实际验证,应该只采用1801端口。

 

Opening Remote Queues with Peek or Receive Access

http://msdn.microsoft.com/en-us/library/ms699862(v=vs.85).aspx

 

 
msmq 之端口开放问题_第2张图片
 

此时采用的端口根据实际验证,包括135端口。

 

封装内容解析

参见下述组件中的程序源码:

http://msmqjava.codeplex.com/

 

封装的内容如下所示,根据access决定如何openQueue(),根据代码看,如果是创建Queue不传递参数,则为

OpenQueueWithAccess(jniEnv, object, queuePath, MQ_SEND_ACCESS | MQ_RECEIVE_ACCESS);

此时,MQ_SEND_ACCESS | MQ_RECEIVE_ACCESS=3

按照下面代码分析,如果MQ_SEND_ACCESSMQ_RECEIVE_ACCESS同时设置,按MQ_RECEIVE_ACCESS 的openQueue()方式处理...

 

jint OpenQueueWithAccess

        (JNIEnv *jniEnv, jobject object, jstring queuePath, int access)

{

    jclass cls = jniEnv->GetObjectClass(object);

    jfieldID fieldId;

    HRESULT hr;

 

    try {

        MsmqQueue * sender= NULL;

        MsmqQueue * receiver= NULL;

 

        const char *szQueuePath = jniEnv->GetStringUTFChars(queuePath, 0);

        DIAG("OpenQueueWithAccess (%s)\n", szQueuePath );

 

        if (access & MQ_RECEIVE_ACCESS) {

            receiver = new MsmqQueue();

            // dinoch - Wed, 11 May 2005  13:48

            // MQ_ADMIN_ACCESS == use the local, outgoing queue for remote queues. ??

            hr = receiver->openQueue((char *) szQueuePath, MQ_RECEIVE_ACCESS ); // | MQ_ADMIN_ACCESS

            if (hr != 0) {

                delete receiver;

                return hr;

            }

        }

 

        if (access & MQ_SEND_ACCESS) {

            sender = new MsmqQueue();

            // dinoch - Wed, 11 May 2005  13:48

            // MQ_ADMIN_ACCESS == use (local) outgoing queue for remote queues

            hr = sender->openQueue((char *) szQueuePath, MQ_SEND_ACCESS ); // | MQ_ADMIN_ACCESS

            if (hr != 0) {

                delete sender;

                if (receiver!=NULL) delete receiver;

                return hr;

            }

        }

 

        jniEnv->ReleaseStringUTFChars(queuePath, szQueuePath);

 

        int slot= StoreHandles(receiver, sender);

        if (slot == -1) return -2;

 

        // use JNI to set the _queueSlot field on the caller

        fieldId = jniEnv->GetFieldID(cls, "_queueSlot", "I");

        if (fieldId == 0) return -3;

        jniEnv->SetIntField(object, fieldId, (jint)slot);

 

    }

    catch(...) {

        DIAG("openQueue : Exception. \n");

        jniEnv->ExceptionDescribe();

        jniEnv->ExceptionClear();

        hr = -99;

    }

 

    fflush(stdout);

 

    return (jint) hr;

}

 

 

你可能感兴趣的:(msmq)