我按照this示例在Spring中设置TCP客户端。下面是变压器所在的tcpClientServerDemo-context.xml
文件。有人可以帮我删除变压器并按原样发送数据而不做任何修改吗?如果我尝试删除行reply-channel='clientBytes2StringChannel'
或甚至将其设为null,则在构建项目时会出现异常。
<?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="hello.SimpleGateway"
default-request-channel="input"/>
<int-ip:tcp-connection-factory id="client"
type="client"
host="192.86.33.61"
serializer="CustomSerializerDeserializer"
deserializer="CustomSerializerDeserializer"
port="${availableServerSocket}"
single-use="true"
so-timeout="10000"/>
<bean id="CustomSerializerDeserializer" class="hello.CustomSerializerDeserializer" />
<int:channel id="input" />
<int-ip:tcp-outbound-gateway id="outGateway"
request-channel="input"
connection-factory="client"
request-timeout="10000"
reply-timeout="10000"/>
<!-- Server side -->
<!-- When creating the socket factory on the server side, we specify both the serializer and deserializer
which deals with both accepting a stream formatted with the Stx-Etx bytes as well as sending a stream
formatted with the Stx-Etx bytes. -->
<int-ip:tcp-connection-factory id="serverConnectionFactory"
type="server"
port="${availableServerSocket}"
single-use="true"
so-linger="10000"
serializer="Custom1SerializerDeserializer"
deserializer="Custom1SerializerDeserializer"/>
<bean id="Custom1SerializerDeserializer" class="hello.CustomSerializerDeserializer1" />
<int-ip:tcp-inbound-gateway id="gatewayCrLf"
connection-factory="serverConnectionFactory"
request-channel="incomingServerChannel"
error-channel="errorChannel"/>
<!-- We leave a message listener off of this channel on purpose because we hook
one up before the test actually runs (see the unit test associated with this
context file) -->
<int:channel id="incomingServerChannel" />
</beans>
修改
现在我可以使用自定义序列化器/反序列化器发送消息。但不幸的是,我无法收到回复。这是我的序列化器/反序列化器:
public class CustomSerializerDeserializer implements Serializer<String>, Deserializer<String> {
protected final Log logger = LogFactory.getLog(this.getClass());
public void serialize(String input, OutputStream outputStream) throws IOException {
logger.info("inside serialize");
outputStream.write(buildSampleMsg(input));
outputStream.flush();
}
public String deserialize(InputStream inputStream) throws IOException {
logger.info("inside deserialize");
final int bufferSize = 1024;
final char[] buffer = new char[bufferSize];
final StringBuilder out = new StringBuilder();
Reader in = new InputStreamReader(inputStream, "UTF-8");
for (;;) {
int rsz = in.read(buffer, 0, buffer.length);
if (rsz < 0) {
break;
}
out.append(buffer, 0, rsz);
}
logger.info(out.toString());
return out.toString();
}
public byte[] buildSampleMsg(String body){
logger.info("inside buildsamplemsg");
......
return hexStringToByteArray(data);
}
我在序列化程序/反序列化程序的第一行上完成了一些日志记录,但从未打印过日志。这反过来意味着,我们没有得到任何回应。任何帮助将不胜感激。
答案 0 :(得分:1)
删除回复频道是正确的。您没有给出任何错误指示,但必须将网关接口方法返回类型更改为byte []。
修改强>
如果大型机出现垃圾,显然你做错了。将“ABCD”转换为byte[]
后,您应该进行EBCDIC转换(getBytes()
);如果你在字符串中有EBCDIC字符,那将无效。另外,请记住默认的序列化程序会将CRLF(ascii)添加到输出中。如果该大型机可以确定数据本身的消息结束,则可以使用ByteArrayRawSerializer
属性中的serializer
。但是,您将需要自定义deserializer
,因为框架将不知道如何从流构造消息;除非主机在发送回复后关闭套接字,在这种情况下,ByteArrayRawSerializer
将作为deserializer
属性。
用于与大型机(和其他)通信的常用技术是使用1,2或4字节长度的报头(网络字节顺序)。 ByteArrayLengthHeaderSerializer
就是这么做的。
如果大型机需要EBCDIC分隔符,则需要一个自定义串行器/解串器 - 在那里进行EBCDIC转换可能更有意义,将它与应用程序逻辑分开。
您可以阅读有关序列化程序/反序列化程序here的信息。
TCP是一种流媒体协议;这意味着必须为通过TCP传输的数据提供一些结构,因此接收器可以将数据划分为离散消息。连接工厂配置为使用(反)序列化器在消息有效负载和通过TCP发送的位之间进行转换。这是通过分别为入站和出站消息提供解串器和串行器来实现的。提供了许多标准(de)序列化器。
ByteArrayCrlfSerializer
,将字节数组转换为字节流,然后是回车符和换行符(\r\n
)。这是默认(de)序列化程序,可以与telnet一起用作客户端,例如。