首页 > 解决方案 > Java TCP-Server 套接字连接保持活动状态

问题描述

我想在端口 2000 和 2001 上作为 TCP 服务器与我的 TCP 客户端(发送字节流的机器)进行通信。因此,我用 Java 编写了一个 Spring Boot 应用程序。

此问题仅针对 2001 端口:我使用 Camunda 作为 BPMN-Engine 来执行和编排。我像这样开始线程:

package com.example.workflow;

import org.camunda.bpm.engine.delegate.DelegateExecution;
import org.camunda.bpm.engine.delegate.JavaDelegate;

public class StartTCPServersDelegate implements JavaDelegate {
    @Override
    public void execute(DelegateExecution delegateExecution) throws Exception {
        Runnable serverZyklisch = new ServerZyklisch();
        Runnable serverAzyklisch = new ServerAzyklisch((String) delegateExecution.getVariable("param"));
        Thread t1 = new Thread(serverZyklisch);
        t1.start();
        System.out.println("Thread Zyklisch gestartet");
        Thread t2 = new Thread(serverAzyklisch);
        t2.start();
        System.out.println("Thread Azyk. gestartet");
        String val1 = (String) delegateExecution.getVariable("param");
        int valueParam = Integer.parseInt(val1);
        System.out.println("Param ist: "+valueParam);

    }
}

这是我的 ServerAzyklisch 类:

public class ServerAzyklisch implements Runnable, JavaDelegate {
    private ServerSocket ssocket;
    String param;
    HexToByteConverter hexToByteConverter = new HexToByteConverter();
    public ServerAzyklisch(String Pparam) throws IOException {
        ssocket = new ServerSocket(2000);
        param = Pparam;
    }

    public void run() {
        System.out.println(param+"Paraaam");
        InputStream in;
        OutputStream out = null;
        Socket socket;
        while(true){
            try {
                socket = ssocket.accept();
                in = socket.getInputStream();
                out = socket.getOutputStream();
                byte []data = new byte[132];
                int numBytes = 0;
                byte[]durch = hexToByteConverter.hexStringToByteArray("333333330041006400040000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
                byte[]durchlauf = hexToByteConverter.hexStringToByteArray("333333330041006400040000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
                byte[]Pressen1hexdump111 = hexToByteConverter.hexStringToByteArray("33333333003d0064000600000004004001c9c78900010000006f00000000000000000000000000010000000000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005");
                byte[]Pressen1hexdump110 = hexToByteConverter.hexStringToByteArray("33333333003d0064000600000004004001c9c78900010000006e0000000000000000000000000001000000000014000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"+param);
                byte[]Pressen2hexdump = hexToByteConverter.hexStringToByteArray("3333333300400065000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
                byte[]Pressen3hexdump = hexToByteConverter.hexStringToByteArray("3333333300400065001400000000003d01c9c7890001000000c9000000000000000000000000000100000000001e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
                byte[]Pressen3hexdumpNextBohrer = hexToByteConverter.hexStringToByteArray("3333333300400065001400000000003f01c9c789000100000078000000000000000000000000000100000000001e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002");
                byte[]Pressen4hexdumpNextRSCIDBohrer = hexToByteConverter.hexStringToByteArray("33333333003f0065001400000000003d01c9c78900010000007a000000000000000000000000000100000000001e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
                //gleichen Stream zurückschicken, der angekommen ist, für Durchlauf
                while((numBytes = in.read(data)) != -1){
                    System.out.println(Arrays.toString(data));
                    out.write(Pressen1hexdump110);
                    out.write(Pressen2hexdump);
                    out.write(Pressen3hexdumpNextBohrer);
                    //out.write(durchlauf);
                }
            } catch (SocketException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public void execute(DelegateExecution delegateExecution) throws IOException {
          }
}

我每次都会得到不同的结果给我的客户,所以行为总是另一种。但我想将所有三个字节数组一次发送给我的客户。我认为我的 while 循环有问题。你有什么主意吗 ?

标签: javaspring-bootsocketstcpoutputstream

解决方案


根据评论,通信是基于请求-响应对。您需要从客户端读取 3 条消息,并为每条消息返回一个响应。为此,请将while循环替换为:

            readMessage(in, data);
            out.write(Pressen1hexdump110);

            readMessage(in, data);
            out.write(Pressen2hexdump);

            readMessage(in, data);
            out.write(Pressen3hexdumpNextBohrer);

其中readMessage方法是您必须添加的新方法,它从客户端读取完整的请求。

如果客户端请求总是 128 字节,有一个方便的方法DataInputStream可以使用:

void readMessage(InputStream in, byte[] buffer) throws IOException {
    new DataInputStream(in).readFully(buffer, 0, 128);
}

在一般情况下,该readMessage方法必须在伪代码中看起来像这样:

void readMessage(InputStream in, byte[] buffer) {
    // Read a message
    while message is not complete:
        read from "in" into "buffer"
        if "in" was closed: throw an exception because the connection was closed mid-request
        else: incorporate newly read data from "buffer" in message
    done
}

推荐阅读