首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Java套接字写入问题

Java套接字写入问题
EN

Stack Overflow用户
提问于 2021-11-02 16:15:00
回答 2查看 58关注 0票数 0

我正在尝试创建Modbus设置,如下所示:

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

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

问题是IED从主服务器接收存储在字节数组中的请求,但将请求传输到服务器不起作用。Wireshark跟踪显示已与服务器建立TCP连接,但未传输请求。

请参见以下代码:

代码语言:javascript
运行
复制
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屏幕快照

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-11-07 08:14:38

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

请在下面找到修改后的ClientHandler代码

代码语言:javascript
运行
复制
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");
        }
    }
}
票数 0
EN

Stack Overflow用户

发布于 2021-11-02 22:19:38

DataOutputStream.write()之后调用DataOutputStream.flush()强制发送字节

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69813663

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档