简体   繁体   English

是否有可能从不同 class 的同一端口上的套接字写入/读取

[英]Is there a possiblity to write/read from a socket on same port from different class

Im having Spring Boot Application for communication between Machines (tcp Clients) and TCP Server (localhost).我有 Spring 引导应用程序用于机器(tcp 客户端)和 TCP 服务器(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:因此我启动了我的 Spring 引导应用程序:

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.在那里我启动了不同的线程,以便客户端(例如 10.50.12.174 = Press,10.50.12.204 = Drill)可以通过套接字连接连接到 TCP 服务器。

My ServerAzyklisch class is like this:我的 ServerAzyklisch class 是这样的:

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.现在我想将其他类中的“while 循环”(带有 out.write)外包,以使用与 ServerAzyklisch 运行方法中的 Socket 的连接。

Therefore I wrote for example a Class Presse.java因此,我写了例如 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.我想从这个 class 发送我的 3 条消息,就像在 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.我知道这是因为我第二次做 Socket.accept,但我不明白我如何才能实现这一点。 Do I have to close socket connection?我必须关闭套接字连接吗? If yes where and with which Java Command?如果是,在哪里以及使用哪个 Java 命令?

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.如果您想在您的程序中拥有多个“Presse”实例,那么您至少需要从中删除ServerSocket Instead, you should accept the connection from the client somewhere else, and pass the client socket to the Presse constructor:相反,您应该在其他地方accept来自客户端的连接,并将客户端套接字传递给Presse构造函数:

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.通常你只想创建一个ServerSocket ,然后在一个循环中调用accept 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.这样服务器可以 go 并接受新的连接。 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
    });
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM