繁体   English   中英

Java套接字写入问题

[英]Java socket write issues

我正在尝试按如下方式创建 Modbus 设置:

客户端 <----> IED <----> Modbus 服务器

IED 的 IP 为 192.168.xx,Modbus 服务器使用 localhost 作为 IP。 所有实体都在同一个 VM 中。 客户端应该向 IED 发送请求,IED 将其转发给服务器,服务器响应 IED。

问题是 IED 接收来自主机的请求,该请求存储在字节数组中,但无法将请求传输到服务器。 Wireshark 跟踪显示与服务器建立了 TCP 连接,但未传输请求。

请参阅下面的代码:

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

还可以在下面找到,wireshark 截图Wireshark 跟踪

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

我设法解决了它。 我错误地将clientSocket而不是modbusSocket作为参数传递给modbus_inmodbus_out Stream 实例。 我还必须在读取和写入之前轮询数据的可用性。 另外,我注意到客户端关闭了 TCP 会话,而服务器端打开了它。 所以我确保在每次查询后关闭连接。

请在下面为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");
        }
    }
}

暂无
暂无

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

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