Apache MINA networking - How to get data from org.apache.mina.core.service.IoHandlerAdapter messageRecieved(IoSession, Object) - apache-mina

public void messageReceived(IoSession session, Object message) throws Exception
{
// do something
}
Can anyone tell me how to get data from the Object?

It's really quite simple, just cast the message into an IoBuffer and pull out the bytes.
// cast message to io buffer
IoBuffer data = (IoBuffer) message;
// create a byte array to hold the bytes
byte[] buf = new byte[data.limit()];
// pull the bytes out
data.get(buf);
// look at the message as a string
System.out.println("Message: " + new String(buf));

Cast message to the object type you used in the client's session.write.

Related

#JmsListener throwing MessageConversionException

I'm trying to receive a message asynchronously from IBM MQ:
#JmsListener(destination = "queue", containerFactory = "Factory", id = "start")
public Mono<Void> requestProcess(Message message) {return Mono.just("").then();
}
Catch:
Caused by: org.springframework.jms.support.converter.MessageConversionException: Cannot convert object of type [reactor.core.publisher.MonoLift] to JMS message. Supported message payloads are: String, byte array, Map<String,?>, Serializable object.
If I switch method type to simple void it works as supposed to. How can I set listener to receive messages in non-blocking reactive way?
The conversion that is failing is the input to requestProcess.
#JmsListener has a found a publisher of type reactor.core.publisher.MonoLift, but requestProcess is expecting a Message, and it doesn't have a conversion.
The way round this would be to changed the input signature for requestProcess to
#JmsListener(destination = "queue", containerFactory = "Factory", id = "start")
public Mono<Void> requestProcess(MonoLift<?> publisher) {
...
}
and modify the method body accordingly.

How can i import this Dll

I have a "CLock.dll" have some functions
For example: This is document for a function
__int16 __stdcall dv_get_auth_code(unsigned char* auth);
Function
To gain authorization code of setup card.
Parameters
auth:[out] Return authorization code, 6 characters.
Return
Succeed then return 0.
I need to call this dll in my winform application. I try
[DllImport("CLock.dll",CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
public static extern int dv_get_auth_code([Out]StringBuilder auth);`
and in Main()
My code:
StringBuilder sb = new StringBuilder();
int result = dv_get_auth_code(sb);
But it's working. What should i do? Thank you and have a nice day !
There are two mistakes in the code as presented. The return type is wrong, and no buffer is allocated.
The return type is a 16 bit type, in C# that is short:
[DllImport("Clock.dll")]
public static extern short dv_get_auth_code(StringBuilder auth);
Then to call the function you need to allocate a buffer. I don't know how large that buffer should be, presumably you know that.
StringBuilder sb = new StringBuilder(bufferLengtg);
short result = dv_get_auth_code(sb);
It is always wise for such an API to pass the length of the buffer to the function. Then it can make sure it does not overrun the buffer.

Apache Commons Crypto - Getting IllegalBlockSizeException

I am trying to use the following method to handle both encryption and decryption of AES data using Apache Commons Crypto. Encryption is working fine. But when I try to decrypt the data I just encrypted, I am getting this block size error, which I don't totally understand since I'm setting the blocksize to 1024, which of course is a multiple of 16.
javax.crypto.IllegalBlockSizeException: Input length (with padding) not multiple of 16 bytes
Here is my code:
final int bufferSize = 1024;
try {
this.cryptoCipher.init(cipherMode, this.secretKeySpec, this.ivParameterSpec);
ByteBuffer inBuffer = ByteBuffer.allocateDirect(bufferSize);
ByteBuffer outBuffer = ByteBuffer.allocateDirect(bufferSize);
inBuffer.put(getUTF8Bytes(dataToBeEncrypted));
inBuffer.flip();
int updateBytes = this.cryptoCipher.update(inBuffer, outBuffer);
int finalBytes = this.cryptoCipher.doFinal(inBuffer, outBuffer); <<<< EXCEPTION HAPPENS HERE!!!
byte[] encoded = new byte[updateBytes + finalBytes];
outBuffer.flip();
outBuffer.duplicate().get(encoded);
encryptedDecryptedData = DatatypeConverter.printBase64Binary(encoded);
} catch (Exception exc) {
LOGGER.logp(Level.SEVERE, MODULE_NAME, methodName, "encountered exception: {0}", exc);
}
AES has one block size: 16-bytes so setting the block size to another value is an error. But you are not setting the block size, just creating a buffer of (in this case) 1024 bytes.
Most implementations accept an array and will internally process the input a block at a time. But the input must be an exact multiple of the block size and that is accomplished with padding, usually PKCS#7 padding, and by an option handles this automatically by adding on encryption and removing on decryption.

When does JNI decide that it can release memory?

When I return a direct ByteBuffer to JNI, how long until it can get reclaimed by the JVM/GC?
Suppose I have a function like this:
void* func()
{
[ ... ]
jobject result = env->CallStaticObjectMethod(testClass, doSomethingMethod);
void* pointerToMemory = env->GetDirectBufferAddress(result);
return pointerToMemory;
}
The JVM can't possibly know how long I'm going to use that pointerToMemory, right? What if I want to hold on to that address and the corresponding memory for a while?
Suppose I want to circumvent this issue and return a byte[] from Java to JNI like this:
ByteBuffer buf;
byte[] b = new byte[1000];
buf = ByteBuffer.wrap(b);
buf.order(ByteOrder.BIG_ENDIAN);
return buf.array();
AND THEN do the same as above, I store a pointer to that byte[] and want to hold on to it for a while. How / when / why is the JVM going to come after that backing byte[] from Java?
void* function()
{
jbyteArray byteArr = (jbytearray)env->CallStaticObjectMethod(testClass, doSomethingMethod);
jbyte *b= env->GetByteArrayElements(byteArr, 0);
return b;
}
The short answer is: If the function implements a native method, the pointer will be invalid as soon as you return.
To avoid this, you should get a global reference for all objects that you intend to keep valid after returning. See the documentation on local and global references for more information.
To understand better how JNI manages references from native code, see the documentation on PushLocalFrame/PopLocalFrame.

WCF: Message Framing and Custom Channels

I am trying to understand how I would implement message framing with WCF. The goal is to create a server in WCF that can handle proprietary formats over Tcp. I can't use the net.Tcp binding because that is only for SOAP.
I need to write a custom channel that would receive messages in the following format
. An example message would be "5 abcde". In particular I am not sure how to do framing in my custom channel.
Here is some sample code
class CustomChannel: IDuplexSessionChannel
{
private class PendingRead
{
public NetworkStream Stream = null;
public byte[] Buffer = null;
public bool IsReading = false;
}
private CommunicationState state = CommunicationState.Closed;
private TcpClient tcpClient = null;
private MessageEncoder encoder = null;
private BufferManager bufferManager = null;
private TransportBindingElement bindingElement = null;
private Uri uri = null;
private PendingRead pendingRead;
public CustomChannel(Uri uri, TransportBindingElement bindingElement, MessageEncoderFactory encoderFactory, BufferManager bufferManager, TcpClient tcpClient)
{
this.uri = uri;
this.bindingElement = bindingElement;
this.tcpClient = tcpClient;
this.bufferManager = bufferManager;
state = CommunicationState.Created;
}
public IAsyncResult BeginTryReceive(TimeSpan timeout, AsyncCallback callback, object state)
{
if (this.state != CommunicationState.Opened) return null;
byte[] buffer = bufferManager.TakeBuffer(tcpClient.Available);
NetworkStream stream = tcpClient.GetStream();
pendingRead = new PendingRead { Stream = stream, Buffer = buffer, IsReading = true };
IAsyncResult result = stream.BeginRead(buffer, 0, buffer.Length, callback, state);
return result;
}
public bool EndTryReceive(IAsyncResult result, out Message message)
{
int byteCount = tcpClient.Client.EndReceive(result);
string content = Encoding.ASCII.GetString(pendingRead.buffer)
// framing logic here
Message.CreateMessage( ... )
}
}
So basically the first time around EndTryReceive could just get a piece of the message from the pending read buffer "5 ab". Then the second time around it could get the rest of the message. The problem is when EndTryReceive gets called the first time, I am forced to create a Message object, this means that there will be a partial Message going up the channel stack.
What I really want to do is to make sure that I have my full message "5 abcde" in the buffer, so that when I construct the message in EndTryReceive it is a full message.
Does anyone have any examples of how they are doing custom framing with WCF?
Thanks,
Vadim
Framing at the wire level is not something that the WCF channel model really cares about; it's pretty much up to you to handle it.
What I mean by this is that it is your responsibility to ensure that your transport channel returns "entire" messages on a receive (streaming changes that a bit, but only up to a point).
In your case, it seems you're translating receive operations on your channel directly into receive operations on the underlying socket, and that just won't do, because that won't give you a chance to enforce your own framing rules.
So really, a single receive operation on your channel might very well translate to more than one receive operation on the underlying socket, and that's fine (and you can still do all that async, so it doesn't need to affect that part).
So basically the question becomes: what's your protocol framing model look like? Wild guess here, but it looks like messages are length prefixed, with the length encoded as a decimal string? (looks annoying).
I think your best bet in that case would be to have your transport buffer incoming data (say, up to 64KB of data or whatever), and then on each receive operation check the buffer to see if it contains enough bytes to extract the length of the incoming message. If so, then either read as many bytes as necessary from the buffer, or flush the buffer and read as many bytes from the socket. You'll have to be careful as, depending on how your protocol works, I'm assuming you might end up reading partial messages before you actually need them.
I agree with the thomasr. You can find some basic inspiration in Microsoft Technology Sample "ChunkingChannel".