简体   繁体   中英

Java socket write issues

I am trying to create a Modbus setup as follows:

client <----> IED <----> Modbus Server

IED has the IP 192.168.xx and Modbus Server uses localhost as IP. All entities are in the same VM. The client is supposed to send a request to the IED,the IED forwards it to the server and the server responds to the IED.

The problem is the IED receives the request from the master which is stored in a byte array but transmitting the request to the server does not work. Wireshark traces show that the TCP connection is established with the server but request is not transmitted.

See the code below:

public class App {
    public static void main(String[] args) {
        IEDServer iedServer = new IEDServer();
        iedServer.start(502);
    }    
}

import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;

public class IEDServer {
    private ServerSocket serverSocket;

    public void start (int port){
        try {
            InetAddress inetAddress = InetAddress.getByName("192.168.20.138");
            serverSocket = new ServerSocket(port, 1024, inetAddress);
            while (true){
                new ClientHandler(serverSocket.accept()).start();
                System.out.println("Connection accepted");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    public void stop(){
        try {
            serverSocket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

import java.io.*;
import java.net.Socket;

public class ClientHandler extends Thread{
    private Socket clientSocket;

    private DataOutputStream out;
    private DataInputStream in;


    public ClientHandler(Socket clientSocket) {
        this.clientSocket = clientSocket;
    }

    @Override
    public void run() {
        try {
            //connection from client
            out = new DataOutputStream (clientSocket.getOutputStream());
            in = new DataInputStream(clientSocket.getInputStream());
//            in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
//            String readline;

            //for connection to modbus server
            Socket modbusSocket = new Socket("127.0.0.1",502);
            modbusSocket.setSoTimeout(10000);
            DataOutputStream modbus_out = new DataOutputStream (clientSocket.getOutputStream());
            DataInputStream modbus_in = new DataInputStream(clientSocket.getInputStream());
            byte [] modbus_bytes = {};

            //read Modbus bytes from client to get client request
            modbus_bytes = in.readAllBytes();

            System.out.println("Modbus request: ");
            for (byte b: modbus_bytes){
                System.out.print(b);
            }
            System.out.println();

            //transfer modbus request to modbus server
            modbus_out.write(modbus_bytes, 0, modbus_bytes.length);

            //get response from modbus server
            modbus_bytes = modbus_in.readAllBytes();

            System.out.println("Modbus response: ");
            for (byte b: modbus_bytes){
                System.out.print(b);
            }
            System.out.println();

            //transfer response to client
            out.write(modbus_bytes,0,modbus_bytes.length);

        } catch (IOException e) {
            e.printStackTrace();
        }

        //close TCP connection
        try {
            in.close();
            out.close();
            clientSocket.close();
            System.out.println("Connection terminated");
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("Connection termination failed");
        }
    }
}

Also find below, the wireshark screenshotWireshark 跟踪

呼叫DataOutputStream.flush()DataOutputStream.write()来强制字节是发送

I managed to fix it. I mistakenly passed clientSocket instead of modbusSocket as a parameter to the modbus_in and modbus_out Stream instances. I also had to poll for availability of data before reading and then writing. Also, I noticed that the client-side closed the TCP session while the server-side had it open. So I ensured that the connection was closed after each query.

Please find modified code below for ClientHandler :

import java.io.*;
import java.net.Socket;

public class ClientHandler extends Thread {
    private Socket clientSocket;
    private Socket modbusSocket;

    private DataOutputStream out, modbus_out;
    private DataInputStream in, modbus_in;

    public ClientHandler(Socket clientSocket) {
        this.clientSocket = clientSocket;
        System.out.println(clientSocket.getInetAddress());

        try {
            out = new DataOutputStream(new BufferedOutputStream(clientSocket.getOutputStream()));
            in = new DataInputStream(new BufferedInputStream(clientSocket.getInputStream()));

//            in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
//            String readline;

            //for connection to modbus server
            modbusSocket = new Socket("127.0.0.1", 502);
            //            modbusSocket.setSoTimeout(10000);
            modbus_out = new DataOutputStream(new BufferedOutputStream(modbusSocket.getOutputStream()));
            modbus_in = new DataInputStream(new BufferedInputStream(modbusSocket.getInputStream()));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void run() {
        try {
            //connection from client
            if (in.available() > 0) {
                //read Modbus bytes from client to get client request
                System.out.println("===============Begin reading===============");
                byte[] modbus_bytes = new byte[in.available()];
                in.read(modbus_bytes);
                System.out.println("Modbus request: ");
                for (byte b : modbus_bytes) {
                    System.out.print(b);
                }
                System.out.println();

                //transfer modbus request to modbus server
                modbus_out.write(modbus_bytes);
                modbus_out.flush();
                System.out.println("Written to modbus server");

                while (modbus_in.available() == 0) {
                    System.out.println("Waiting for device response...");
                }
                System.out.println("\nDevice response ready");

                //get response from modbus server
                modbus_bytes = new byte[modbus_in.available()];
                modbus_in.read(modbus_bytes);

                System.out.print("Modbus response: ");
                for (byte b : modbus_bytes) {
                    System.out.print(b);
                }
                System.out.println("\nSending response to client");

                //transfer response to client
                out.write(modbus_bytes);
                out.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        //close TCP connection
        try {
//            in.close();
//            out.close();
            clientSocket.close();
            modbusSocket.close();
            System.out.println("===========Connection terminated==============");
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("Connection termination failed");
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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