java - Spring集成tcp-connection-factory在回复之前关闭客户端连接

标签 java spring sockets tcp spring-integration

我在 spring 集成方面遇到一些问题。 可以说,这是我的传出通信配置:

<int:channel id="outputChannel">
    <int:queue /> 
</int:channel>

<int:channel id="outputChannel-in"> <!-- for response from server -->
    <int:queue /> 
</int:channel>

<int-ip:tcp-connection-factory 
    id="outputSocket"
    type="client" 
    single-use="true"
    host="localhost"
    port="666" />

<int-ip:tcp-outbound-gateway id="outGateway"
    request-channel="outputChannel"
    reply-channel="outputChannel-in"
    connection-factory="outputSocket"
    reply-timeout="20000" />

<int:gateway id="myGateway"
     service-interface="some.package.SocketGateway"
     default-request-channel="outputChannel"
     default-reply-channel="outputChannel-in" />

<int:service-activator
    id="myServiceActivator" 
    input-channel="outputChannel-in" 
    ref="myService"
    method="incomingDataHandlingMethod" />

无论我将如何处理接口(interface) some.package.SocketGateway:

选项#1:

public interface SocketGateway{
    byte[] send(String text);
}

选项#2:

public interface SocketGateway{
    Future<byte[]> send(String text);
}

它没有收到任何消息。 我经常玩配置。这只是我的解决方案的一个版本,但没有一个有效。

这是一个服务器模拟:

ServerSocket someSocket = new ServerSocket(666);
Socket socket = someSocket.accept();

PrintWriter  out =
    new PrintWriter (socket.getOutputStream(), true);
BufferedReader in =
    new BufferedReader(
        new InputStreamReader(socket.getInputStream()));

System.out.println("socket accepted");

String data = in.readLine();
while (data != null) {
    System.out.println(data);
    data = in.readLine();
} 

System.out.println("data received");
out.println("ACK");

out.flush();  
System.out.println("data sent");
socket.close();
someSocket.close();

out.println("ACK"); 过了 while 后,连接关闭并且不发送 ACK。当 out.println("ACK"); 位于 while 或 inside 之前时,发送消息。

我应该做什么才能收到此消息?

编辑: 我也尝试过:

<int-ip:tcp-outbound-channel-adapter
    id="outboundClient"
    channel="outputChannel"
    connection-factory="outputSocket" />

<int-ip:tcp-inbound-channel-adapter
    id="outboundClient-in"
    channel="outputChannel-in"
    connection-factory="outputSocket" />

没有好的结果。

编辑: 我有这个客户端代码:

Socket echoSocket = new Socket("10.20.30.40", 11111);
PrintWriter out = new PrintWriter(echoSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(echoSocket.getInputStream()));

String encodedMessage = "someMessage";

String result = String.format("%c%s%c%c", (char) 11, encodedMessage, (char) 28, (char) 13);

            out.println(result);
out.flush();
System.out.println("data sent");

File file = new File("result.txt");
BufferedWriter output = new BufferedWriter(new FileWriter(file));

String data;
while ((data = in.readLine()) != null) {
    output.write(data);
}

output.flush();
output.close();

System.out.println("after while");
out.close();
in.close();
echoSocket.close();

这与外部服务器配合得很好(服务器正在同步发送 ACK 消息,该消息在字符串数据中接收。如何使用 Spring Integration 实现此结果?我无法接收任何内容...

最佳答案

TCP是一个流;它需要结构来分隔消息。默认解串器期望结尾处有 CRLF。

发送out.println("ACK\r\n");

您可以阅读有关SerializerDeserializer的信息 here .

编辑:

你的逻辑在几个方面都有缺陷。

  1. 使用PrintWriter.println()仅附加LF;除非您更改解串器,否则您需要 CRLF。
  2. 您的“服务器”卡在 readLine() 上,直到套接字关闭。

这工作正常:

ServerSocket someSocket = new ServerSocket(1666);
Socket socket = someSocket.accept();

OutputStream out = socket.getOutputStream();
BufferedReader in =
    new BufferedReader(
        new InputStreamReader(socket.getInputStream()));

System.out.println(Thread.currentThread().getName() +  " socket accepted");

String data = in.readLine();
System.out.println(data);

System.out.println("data received");
out.write("ACK\r\n".getBytes());

out.flush();
System.out.println("data sent");
socket.close();
someSocket.close();

关于java - Spring集成tcp-connection-factory在回复之前关闭客户端连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27967869/

相关文章:

linux - 当 tcp 服务器在执行 accept 之前绑定(bind)并 fork 时会发生什么?哪个进程将处理客户端请求?

c# - 哪个本地 ip 连接到远程 ip?

java - Spring引导自动配置覆盖自定义(elasticsearchTemplate)配置

java - 在集群上运行 Apache Spark 应用程序时是否可以缓存应用程序 jar?

java - 绑定(bind)Spring的HibernateDaoSupport时如何设置数据源

java - Spring父容器

java - JPA(ebean)部分mysql日期

java初学者-我应该在哪个文件夹中放置 "database.properties"文件

java - 如何为@RequestParam 的默认值提供表达式

c++ - QTcp 服务器 : bind socket with custom options