簡體   English   中英

是否有可能從不同 class 的同一端口上的套接字寫入/讀取

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

我有 Spring 引導應用程序用於機器(tcp 客戶端)和 TCP 服務器(localhost)之間的通信。 我能夠與一台機器/客戶端通信,但我無法與兩台或更多台機器通信。 因此我啟動了我的 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);
  }
}

在那里我啟動了不同的線程,以便客戶端(例如 10.50.12.174 = Press,10.50.12.204 = Drill)可以通過套接字連接連接到 TCP 服務器。

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

現在我想將其他類中的“while 循環”(帶有 out.write)外包,以使用與 ServerAzyklisch 運行方法中的 Socket 的連接。

因此,我寫了例如 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();
    }
}

我想從這個 class 發送我的 3 條消息,就像在 ServerAzyklisch class 中一樣。 但它會拋出錯誤,因為:

Caused by: java.net.BindException: Address already in use: NET_Bind

我知道這是因為我第二次做 Socket.accept,但我不明白我如何才能實現這一點。 我必須關閉套接字連接嗎? 如果是,在哪里以及使用哪個 Java 命令?

如果您想在您的程序中擁有多個“Presse”實例,那么您至少需要從中刪除ServerSocket 相反,您應該在其他地方accept來自客戶端的連接,並將客戶端套接字傳遞給Presse構造函數:

public Presse(Socket clientSocket) throws IOException {
    this.socket = clientSocket;
    //Inputstream
    in = socket.getInputStream();
    //Outputstream
    out = socket.getOutputStream();
}

通常你只想創建一個ServerSocket ,然后在一個循環中調用accept 要一次允許多個客戶端連接,請在單獨的線程中與客戶端通信。 這樣服務器可以 go 並接受新的連接。 這是一個如何使用線程池的框架示例:

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