Java TCP服务器套接字连接保持活动

huangapple go评论119阅读模式
英文:

Java TCP-Server socket connection keepalive

问题

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

这个问题只针对端口2001:
我使用Camunda作为BPMN引擎来执行和编排操作。
我这样启动线程:

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("333333330041006400040000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
                byte[] durchlauf = hexToByteConverter.hexStringToByteArray("333333330041006400040000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
                byte[] Pressen1hexdump111 = hexToByteConverter.hexStringToByteArray("33333333003d0064000600000004004001c9c78900010000006f00000000000000000000000000010000000000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005");
                byte[] Pressen1hexdump110 = hexToByteConverter.hexStringToByteArray("33333333003d0064000600000004004001c9c78900010000006e0000000000000000000000000001000000000014000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + param);
                byte[] Pressen2hexdump = hexToByteConverter.hexStringToByteArray("3333333300400065000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
                byte[] Pressen3hexdump = hexToByteConverter.hexStringToByteArray("3333333300400065001400000000003d01c9c7890001000000c9000000000000000000000000000100000000001e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
                byte[] Pressen3hexdumpNextBohrer = hexToByteConverter.hexStringToByteArray("3333333300400065001400000000003f01c9c789000100000078000000000000000000000000000100000000001e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002");
                byte[] Pressen4hexdumpNextRSCIDBohrer = hexToByteConverter.hexStringToByteArray("33333333003f0065001400000000003d01c9c78900010000007a000000000000000000000000000100000000001e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
                //将到达的数据发送回相同的流,用于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循环中有问题。你有什么想法?

英文:

I want to communicate as a TCP Server on Port 2000 and 2001 with my TCP Client (Machine which sends Bytestreams).
Therefore I programmed a Spring Boot Application in Java.

This Question is only for Port 2001:
I use Camunda as BPMN-Engine for executing and orchestrating.
I start Threads like this:

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);
}
}

This is my ServerAzyklisch Class:

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 {
}
}

I get everytime a different Result to my Client, so the behaviour is always another. But I want to send once all three bytearrays to my Client. I think something is wrong with my while loop.
Do you have any idea ?

答案1

得分: 1

根据评论,通信是基于请求-响应对的。您需要从客户端读取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) {
    // 读取消息
    while 消息未完成:
in读取到buffer
        如果in已关闭抛出异常因为连接在请求中断开
        否则将从buffer中新读取的数据合并到消息中
    完成
}
英文:

By the comments, the communication is based on request-response pairs. You need to read 3 messages from the client, and return a response for each message. To do this, replace the while loop with:

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

where the readMessage method is a new method you must add, that reads a complete request from the client.

If the client requests are always 128 bytes, there is a convenient method in DataInputStream that you can use:

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

In the general case the readMessage method would have to look something like this in pseudo-code:

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
}
</details>

huangapple
  • 本文由 发表于 2020年8月10日 21:58:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/63341686.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定