programming - sockets java examples
El cliente de Spring TCP Socket no recibe datos de Mainframe (2)
Si el mainframe no cierra la conexión al final de la respuesta, como probablemente no lo haga, el bucle de lectura nunca saldrá. El ciclo debe ser consciente de la duración esperada o real de la respuesta de alguna manera.
Los serializadores seguramente también necesitan hacer alguna conversión EBCDIC?
Estoy tratando de usar este ejemplo para enviar y recibir datos hacia y desde una máquina de Mainframe que usa datos HEX
para comunicarse. Entonces tengo lo siguiente en mi configuración:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:int="http://www.springframework.org/schema/integration"
xmlns:int-ip="http://www.springframework.org/schema/integration/ip"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/ip http://www.springframework.org/schema/integration/ip/spring-integration-ip.xsd">
<context:property-placeholder />
<!-- Client side -->
<int:gateway id="gw"
service-interface="org.springframework.integration.samples.tcpclientserver.SimpleGateway"
default-request-channel="input"/>
<int-ip:tcp-connection-factory id="client"
type="client"
host="<ip>"
serializer="CustomSerializerDeserializer"
deserializer="CustomSerializerDeserializer"
port="${availableServerSocket}"
single-use="false"
so-timeout="1800000"
using-nio="false" />
<bean id="CustomSerializerDeserializer" class="org.springframework.integration.samples.tcpclientserver.CustomSerializerDeserializer" />
<int:channel id="input" />
<int-ip:tcp-outbound-gateway id="outGateway"
request-channel="input"
connection-factory="client"
request-timeout="1800000"
reply-timeout="1800000"/>
<!-- Server side -->
<int-ip:tcp-connection-factory id="crLfServer"
type="server"
port="${availableServerSocket}"/>
<int-ip:tcp-inbound-gateway id="gatewayCrLf"
connection-factory="crLfServer"
request-channel="serverBytes2StringChannel"
error-channel="errorChannel"/>
<int:channel id="toSA" />
<int:service-activator input-channel="toSA"
ref="echoService"
method="test"/>
<bean id="echoService"
class="org.springframework.integration.samples.tcpclientserver.EchoService" />
<int:object-to-string-transformer id="serverBytes2String"
input-channel="serverBytes2StringChannel"
output-channel="toSA"/>
</beans>
Y en mi Serializador / Deserializador, tengo el siguiente contenido:
public void serialize(String input, OutputStream outputStream) throws IOException {
outputStream.write(buildmsg(input));
outputStream.flush();
}
public String deserialize(InputStream inputStream) throws IOException {
String data = "";
logger.info("inside deserialize");
DataInputStream dis = new DataInputStream(inputStream);
int len = dis.readInt();
if (len > 0) {
logger.info("len: " + decimaltohex(len));
logger.info("data: " + data);
byte[] b = new byte[dis.available()];
dis.readFully(b);
data += decimaltohex(len);
data += byteArrayToHex(b);
}
logger.info("full data:" + data);
return data;
}
public byte[] buildmsg(String body) throws UnsupportedEncodingException {
String header = "00000000";
String totMsg = header + body;
header = massageheader(decimaltohex(totMsg.length() / 2));
totMsg = header + body;
logger.info("sending data : " + totMsg);
return hexStringToByteArray(totMsg);
}
public String decimaltohex(int data) {
return Integer.toHexString(data);
}
public static String massageheader(String data) {
String str = String.format("%8s", data).replace('' '', ''0'').toUpperCase();
return str;
}
public static byte[] hexStringToByteArray(String s) {
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+ Character.digit(s.charAt(i + 1), 16));
}
return data;
}
public static String byteArrayToHex(byte[] a) {
StringBuilder sb = new StringBuilder(a.length * 2);
for (byte b : a) {
sb.append(String.format("%02x", b));
}
return sb.toString();
}
La entrada en sí misma es una cadena hexagonal (asúmelo). Por lo tanto, el mensaje se está enviando y la respuesta también se recibe correctamente, pero la salida no se transfiere al Servicio de eco. ¿Por qué no está sucediendo eso? ¿Hay algo mal en mi configuración?
Este no es un registro de DEPURACIÓN, solo INFO; su configuración log4j debe estar equivocada.
dentro deserializar
Este es simplemente el hilo de recepción en espera de datos; está atorado en su bucle for esperando a que el mainframe cierre la conexión. Sugiero que agregue alguna depuración dentro del bucle.
EDITAR
El registro de Commons no se encuentra en su POM ...
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
o cambiar a log4j2
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.7</version>
</dependency>
y crea un archivo de configuración log4j2.
Spring Framework 5 ahora usa su propia implementación de commons-logging que no es compatible con log4j 1.x.