使用带有java.net.Socket客户端的ByteArrayLengthHeaderSerializer

时间:2017-01-25 17:15:54

标签: spring spring-integration

我正在尝试使用ByteArrayLengthHeaderSerializer将简单的java.net.Socket TCP客户端连接到Spring Integration TCP服务器。

以下是相关的客户端代码段:

    Socket socket = null;

    OutputStream out = null;
    InputStream in = null;

    try {
        socket = new Socket(host, port);

        out = new BufferedOutputStream(socket.getOutputStream());
        in = new BufferedInputStream(socket.getInputStream());
        byte[] lengthBuf = new byte[4];
        int size = in.read(lengthBuf, 0, lengthBuf.length);

        ByteArrayInputStream bis = new ByteArrayInputStream(lengthBuf);
        ObjectInputStream ois =  new ObjectInputStream(bis);
        int dataSize = ois.readInt();

        System.out.println("Got size: " + dataSize);

        byte[] dataBuffer = new byte[dataSize];

        int dataRead = in.read(dataBuffer, 0, dataBuffer.length);

        bis = new ByteArrayInputStream(dataBuffer);
        ois =  new ObjectInputStream(bis);
        String data = (String) ois.readObject();

        System.out.println("read " + dataRead + " bytes, got data: " + data);

这是服务器端配置:

@MessagingGateway(defaultRequestChannel="toTcp")
public interface Gateway {
    void send(@Payload byte[] data, @Header(IpHeaders.CONNECTION_ID) String connectionId);
}

@Bean
public AbstractServerConnectionFactory serverFactory() {
    AbstractServerConnectionFactory connectionFactory = new TcpNetServerConnectionFactory(port);

    ByteArrayLengthHeaderSerializer serDeser = new ByteArrayLengthHeaderSerializer(); 
    connectionFactory.setSerializer(serDeser);
    connectionFactory.setDeserializer(serDeser);

    return connectionFactory;
}

@Bean
public TcpReceivingChannelAdapter inboundAdapter(AbstractServerConnectionFactory connectionFactory) {
    TcpReceivingChannelAdapter inbound = new TcpReceivingChannelAdapter();

    inbound.setConnectionFactory(connectionFactory);
    inbound.setOutputChannel(fromTcp());

    return inbound;
}

和调用代码:

public void send(String data, String header) throws IOException {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        try (ObjectOutputStream oos = new ObjectOutputStream(bos)) {                
            System.out.println("data.length is " + data.length());
            oos.writeObject(data);

            byte[] bytes = bos.toByteArray();
            gateway.send(bytes, header);
        }
}

当我发送数据时(例如' abc')我得到(在客户端)此错误: invalid stream header: 0000000A 在服务器端,我得到:

SoftEndOfStreamException: Stream closed between payloads

我做错了什么?

1 个答案:

答案 0 :(得分:0)

否 - ObjectOutputStream序列化java对象(以及输入流反序列化)。您不需要长度标题反序列化器,只需使用DefaultSerializerDefaultDeserializer(来自Spring Core)并且不添加标题。

您收到错误,因为序列化在开头添加了更多内容。

或者,如果您只发送一个字符串,则可以使用String.getBytes()并发送长度(4个字节),然后发送byte[]