使用spring集成作为tcp客户端时,如何将EOF信号发送到服务器?

时间:2018-12-26 09:35:12

标签: spring-integration spring-integration-ip

我想使用spring集成来替换套接字客户端。我的套接字客户端代码如下:

public static void main(String[] args) {

    try {
        Socket socket = new Socket("localhost", 7779);
        OutputStream os = socket.getOutputStream();
        PrintWriter pw = new PrintWriter(os);
        String str = "hello server!";
        pw.write(str);
        pw.flush();
        socket.shutdownOutput();
        InputStream is = socket.getInputStream();
        BufferedReader br = new BufferedReader(new InputStreamReader(is));
        String info = br.readLine();
        while (info != null) {
            System.out.println("i am client. server says that " + info);
            info = br.readLine();
            pw.close();
        }
        br.close();
        is.close();
        pw.close();
        socket.close();
    } catch (IOException e) {
        e.printStackTrace();
    }

}

套接字客户端将获得服务器的回复消息。 我使用spring集成来完成相同的工作。 Spring Integration的xml代码是这样的:

    <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="localhost"
                               port="7779"
                               single-use="true"
                               so-timeout="10000"/>

<int:channel id="input"/>

<int-ip:tcp-outbound-gateway id="outGateway"
                             request-channel="input"
                             reply-channel="clientBytes2StringChannel"
                             connection-factory="client"
                             request-timeout="10000"
                             reply-timeout="10000"/>

<int:object-to-string-transformer id="clientBytes2String"
                                  input-channel="clientBytes2StringChannel"/>

这是Spring集成的tcp-client-server示例https://github.com/spring-projects/spring-integration-samples/tree/master/basic/tcp-client-server

的一部分

java代码是这样的:

    final Scanner scanner = new Scanner(System.in);
    final GenericXmlApplicationContext context = Main.setupContext();
    final SimpleGateway gateway = context.getBean(SimpleGateway.class);
    final AbstractServerConnectionFactory crLfServer = context.getBean(AbstractServerConnectionFactory.class);

    TestingUtilities.waitListening(crLfServer, 10000L);

    while (true) {

        final String input = scanner.nextLine();

        if ("q".equals(input.trim())) {
            break;
        }
        else {
            final String result = gateway.send(input);
            System.out.println(result);
        }
    }

    System.out.println("Exiting application...bye.");
    System.exit(0);

}

public static GenericXmlApplicationContext setupContext() {
    final GenericXmlApplicationContext context = new GenericXmlApplicationContext();

    if (System.getProperty(AVAILABLE_SERVER_SOCKET) == null) {
        System.out.print("Detect open server socket...");
        int availableServerSocket = SocketUtils.findAvailableTcpPort(5678);

        final Map<String, Object> sockets = new HashMap<>();
        sockets.put(AVAILABLE_SERVER_SOCKET, availableServerSocket);

        final MapPropertySource propertySource = new MapPropertySource("sockets", sockets);

        context.getEnvironment().getPropertySources().addLast(propertySource);
    }

    System.out.println("using port " + context.getEnvironment().getProperty(AVAILABLE_SERVER_SOCKET));

    context.load("classpath:META-INF/spring/integration/tcpClientServerDemo-context.xml");
    context.registerShutdownHook();
    context.refresh();

    return context;
}

,我无法获得服务器回复,因为服务器没有收到eof信号,并且它仍在readLine()中阻塞; 我得到的例外: org.springframework.integration.MessageTimeoutException:等待响应超时。

这是服务器代码:

try {
        ServerSocket serverSocket = new ServerSocket(7779);
        Socket socket = serverSocket.accept();
        InputStream is = socket.getInputStream();
        InputStreamReader isr = new InputStreamReader(is);
        BufferedReader br = new BufferedReader(isr);
        String info = br.readLine();
        System.out.println("from client : "+info);
        while (info != null) {
            System.out.println("i am server. message from client is " + info);
            info = br.readLine(); //server blocked here
        }
        socket.shutdownInput();
        OutputStream os = socket.getOutputStream();
        String replyMsg="welcom from server 7779 ACK\r\n";
        os.write(replyMsg.getBytes());
        os.close();
        br.close();
        isr.close();
        is.close();
        socket.close();
        serverSocket.close();
    } catch (IOException e) {
        e.printStackTrace();
    }

那么我如何将eof信号发送到服务器,以便我的应用程序将获得服务器的答复?

1 个答案:

答案 0 :(得分:0)

Spring Integration当前不支持那些shutDown*()方法。

请打开GitHub Issue,我们来看一下。