Im having Spring Boot Application for communication between Machines (tcp Clients) and TCP Server (localhost). I am able to communicate with one machine/client, but I cant communicate with 2 or more machines. Therefore I start my Spring Boot Application:
package com.example.workflow;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import java.io.IOException;
@SpringBootApplication
public class Application {
public static void main(String[] args) throws IOException {
Runnable serverZyklisch = new ServerZyklisch();
Runnable serverAzyklisch = new ServerAzyklisch();
for (int i = 0; i < 4; i++) {
new Thread(serverZyklisch).start();
new Thread(serverAzyklisch).start();
}
SpringApplication.run(Application.class);
}
}
There I have different Threads started, so that the clients (for example 10.50.12.174 = Press, 10.50.12.204 = Drill) can connect to TCP Server over Socket Connection.
My ServerAzyklisch class is like this:
package com.example.workflow;
import org.camunda.bpm.engine.delegate.DelegateExecution;
import org.camunda.bpm.engine.delegate.JavaDelegate;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class ServerAzyklisch implements Runnable, JavaDelegate {
int count = 0;
private final ServerSocket ssocket;
static String param = StartTCPServersDelegate.parameter;
HexToByteConverter hexToByteConverter = new HexToByteConverter();
// 2 TCP Server starten Port 2000, Port 2001
public ServerAzyklisch(String Pparam) throws IOException {
ssocket = new ServerSocket(2000);
param = Pparam;
}
public ServerAzyklisch() throws IOException {
ssocket = new ServerSocket(2000);
}
public void run() {
byte[] buf = new byte[1];
System.out.println(param+"Paraaam");
InputStream in;
OutputStream out = null;
Socket socket = null;
//Thread immer aktiv
int n = 0;
while(true){
try {
// Wartet auf Socket Verbindung
System.out.println("Server is listening on port "+ ssocket.getLocalPort());
socket = ssocket.accept();
count++;
System.out.println("Countet clients: "+count);
socket.setSoLinger(true, 1000);
System.out.println("Sockeport: "+socket.getLocalPort());
System.out.println("Connection from " + socket.getInetAddress().toString());
//Inputstream
in = socket.getInputStream();
//Outputstream
out = socket.getOutputStream();
//Datenpuffer deklarieren (anlegen)
byte []data = new byte[132];
byte[]Pressen1hexdump110 = hexToByteConverter.hexStringToByteArray("33333333003d0064000600000004004001c9c78900010000006e0000000000000000000000000001000000000014000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"+param);
byte[]Pressen2hexdump = hexToByteConverter.hexStringToByteArray("3333333300400065000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
byte[]Pressen3hexdump = hexToByteConverter.hexStringToByteArray("3333333300400065001400000000004001c9c6e900010000006e000000000000000000000000000100000000001e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
in.read(buf);
while (buf[0] != -1) {
out.write(Pressen1hexdump110);
out.write(Pressen2hexdump);
out.write(Pressen3hexdump);
}
} catch (IOException e) {
e.printStackTrace();
}catch (Exception e) {
e.printStackTrace();
}
}
}
@Override
public void execute(DelegateExecution delegateExecution) throws IOException {
}
}
Now I want to outsource the "while loop" (with out.write) in other Classes to use the connection to Socket like in ServerAzyklisch run method.
Therefore I wrote for example a Class Presse.java
package com.example.workflow;
import org.camunda.bpm.engine.delegate.DelegateExecution;
import org.camunda.bpm.engine.delegate.JavaDelegate;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class Presse implements JavaDelegate {
ServerSocket ssocket;
private HexToByteConverter hexToByteConverter = new HexToByteConverter();
Socket socket;
InputStream in;
OutputStream out;
byte[]Pressen1hexdump110 = hexToByteConverter.hexStringToByteArray("33333333003d0064000600000004004001c9c78900010000006e00000000000000000000000000010000000000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005");
byte[]Pressen2hexdump = hexToByteConverter.hexStringToByteArray("3333333300400065000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
byte[]Pressen3hexdump = hexToByteConverter.hexStringToByteArray("3333333300400065001400000000004001c9c6e900010000006e000000000000000000000000000100000000001e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
public Presse() throws IOException {
ssocket = new ServerSocket(2000);
socket = ssocket.accept();
//Inputstream
in = socket.getInputStream();
//Outputstream
out = socket.getOutputStream();
}
public void sendMessage(InputStream in, OutputStream out, byte[]message) throws IOException {
out.write(Pressen1hexdump110);
out.write(Pressen2hexdump);
out.write(Pressen3hexdump);
socket.close();
}
@Override
public void execute(DelegateExecution delegateExecution) throws Exception {
PostRequestDelegate postRequestDelegate = new PostRequestDelegate();
postRequestDelegate.post();
}
}
I want to send my 3 messages from this class, like in ServerAzyklisch class. But it throws Error because:
Caused by: java.net.BindException: Address already in use: NET_Bind
I know this because is I do Socket.accept a second time, but I dont understand how I can achieve this to work. Do I have to close socket connection ? If yes where and with which Java Command ?
If you want to have more than one instances of "Presse" in your program, the very least you'll need to remove ServerSocket
from it. Instead, you should accept
the connection from the client somewhere else, and pass the client socket to the Presse
constructor:
public Presse(Socket clientSocket) throws IOException {
this.socket = clientSocket;
//Inputstream
in = socket.getInputStream();
//Outputstream
out = socket.getOutputStream();
}
Usually you want to create only one ServerSocket
, and call accept
on it in a loop. To allow more than one client to connect at a time, communicate with the client in a separate thread. This way the server can go and accept a new connection. Here's a skeleton example of how to use a thread pool for this:
int maxClients = 10;
ExecutorService threadPool = Executors.newFixedThreadPool(maxClients);
ServerSocket serverSocket = new ServerSocket(2000);
while (true) {
Socket clientSocket = serverSocket.accept();
threadPool.submit(() -> {
// Communicate with clientSocket, for example:
Presse p = new Presse(clientSocket);
// You'll want to have this code in a separate method
});
}