Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
package org.bidib.jbidibc.netbidib.client;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;
import java.util.concurrent.Callable;
import java.util.concurrent.atomic.AtomicBoolean;
import org.bidib.jbidibc.messages.exception.ProtocolException;
import org.bidib.jbidibc.messages.utils.ByteUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* This class is the handler for TCP client connections. Every client connection is handled with its own handler
* instance.
*/
public class NetBidibClientSocketHandler implements Callable {
private static final Logger LOGGER = LoggerFactory.getLogger(NetBidibClientSocketHandler.class);
protected static final Logger MSG_RAW_LOGGER = LoggerFactory.getLogger("RAW");
private final InputStream socketInputStream;
private final NetMessageHandler netMessageHandler;
private AtomicBoolean runEnabled = new AtomicBoolean();
private ByteArrayOutputStream receiveBuffer = new ByteArrayOutputStream(2048);
private final InetAddress remoteAddress;
private final int portNumber;
public NetBidibClientSocketHandler(final InputStream socketInputStream, final InetAddress remoteAddress,
final int portNumber, final NetMessageHandler netMessageHandler) {
this.socketInputStream = socketInputStream;
this.netMessageHandler = netMessageHandler;
this.remoteAddress = remoteAddress;
this.portNumber = portNumber;
}
@Override
public Void call() {
runEnabled.set(true);
byte[] receiveData = new byte[1024];
try (BufferedInputStream in = new BufferedInputStream(socketInputStream)) {
int receivedCount = 0;
// wait for client sending data
while ((receivedCount = in.read(receiveData)) > 0 && runEnabled.get()) {
// forward processing to handler
if (netMessageHandler != null) {
// LOGGER.info("Received a packet. Forward packet to messageReveiver: {}", messageReceiver);
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Received data: {}", ByteUtils.bytesToHex(receiveData, receivedCount));
}
// append the received data to the buffer
receiveBuffer.write(receiveData, 0, receivedCount);
// the received data can contain more than a single packet !!!!
// 11:36:23.529 [INFO] org.bidib.jbidibc.net.NetBidibTcpPort [pool-26-thread-1] - Received data:
// 00 01 00 09 FE 05 00 05 90 01 01 D8 FE 00 01 00 0A FE 05 00 06 90 02 01 05 FE 00 01 00 0B FE
// 05 00 07 90 03 64 14 FE
try {
parsePackets(receiveBuffer, netMessageHandler, remoteAddress, portNumber);
}
catch (Exception pex) {
LOGGER.warn("Receive message failed.", pex);
}
finally {
receiveBuffer.reset();
}
}
else {
LOGGER
.warn("No message receiver configured, data: {}",
ByteUtils.bytesToHex(receiveData, receivedCount));
}
}
}
catch (IOException ex) {
if (runEnabled.get()) {
LOGGER.warn("--- Interrupt NetBidibTcpPort-run", ex);
}
else {
LOGGER.info("The NetBidibTcpPort worker is terminating.");
}
}
finally {
LOGGER.info("The socket connection was closed.");
// if (socketInputStream != null) {
// try {
// socketInputStream.close();
// }
// catch (IOException ex) {
// LOGGER.warn("Close socket failed.", ex);
// }
// socketInputStream = null;
// }
if (netMessageHandler != null) {
LOGGER.info("Cleanup the messageReceiver.");
// say goodbye to the message receiver to cleanup resources
String remoteHost = remoteAddress.getHostAddress() + ":" + portNumber;
netMessageHandler.cleanup(remoteHost);
}
LOGGER.info("Cleanup work after close socked has finished.");
}
return null;
}
protected void parsePackets(
final ByteArrayOutputStream output, final NetMessageHandler netMessageHandler, InetAddress address,
int portNumber) throws ProtocolException {
// iterate over the data and find the packets and strip out all serial encoding
try {
parseInput(output, netMessageHandler, address, portNumber);
}
catch (RuntimeException pex) {
LOGGER.warn("Receive message failed, reason: {}", pex.getMessage());
}
finally {
// append the remaining data
output.reset();
}
}
private void processMessages(
final ByteArrayOutputStream output, final NetMessageHandler netMessageHandler, InetAddress address,
int portNumber) throws ProtocolException {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Process messages will put data into DataPacket: {}", ByteUtils.bytesToHex(output));
}
// publish the packet
// do not add the CRC to the data packet
final DataPacket receivedPacket =
new DataPacket(output.toByteArray(), 0, output.size() /*- 1*/, address, portNumber);
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Received data: {}", ByteUtils.bytesToHex(receivedPacket.getData()));
}
netMessageHandler.receive(receivedPacket);
}
private ByteArrayOutputStream outputBuffer = new ByteArrayOutputStream(100);
/**
* Parse the received data to process the received bidib packets.
*
* @param receiveData
* the receive data stream
* @param netMessageHandler
* the message receiver
* @param address
* the address from where the data was received
* @param portNumber
* the port number
* @throws ProtocolException
*/
protected void parseInput(
final ByteArrayOutputStream receiveData, final NetMessageHandler netMessageHandler, InetAddress address,
int portNumber) throws ProtocolException {
if (receiveData != null) {
int receivedCount = receiveData.size();
byte[] receivedData = receiveData.toByteArray();
MSG_RAW_LOGGER.info("<<<< len: {}, data: {}", receivedCount, ByteUtils.bytesToHex(receiveData));
try {
outputBuffer.write(receivedData);
}
catch (IOException ex) {
LOGGER.warn("Copy received data to output buffer failed.", ex);
throw new ProtocolException("Copy received data to output buffer failed.");
}
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Received raw message: {}", ByteUtils.bytesToHex(outputBuffer));
}
if (MSG_RAW_LOGGER.isInfoEnabled()) {
MSG_RAW_LOGGER.info("<< [{}] - {}", outputBuffer.size(), ByteUtils.bytesToHex(outputBuffer));
}
// if a CRC error is detected in splitMessages the reading loop will terminate ...
try {
processMessages(outputBuffer, netMessageHandler, address, portNumber);
outputBuffer.reset();
}
catch (ProtocolException ex) {
LOGGER.warn("Process messages failed.", ex);
// TODO handle this error
}
}
else {
LOGGER.error("No input available.");
}
}
public void stop() {
LOGGER.info("Stop the socket handler.");
this.runEnabled.set(false);
}
}