0

我似乎在这里遗漏了一些微不足道的东西。我正在使用 java 为树莓派编写一个应用程序和一个桌面命令行来配合它。我可以向 pi 发送数据,它会响应,但桌面应用程序没有收到回复(这是我想要的)。不抛出异常。

这是代码: Pi 代码:

package raspberrypiapp;

import java.awt.Color;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Michael
 */
public class RemoteControlManager implements Runnable {

    ServerSocket s;
    Socket socket;
    DataOutputStream dout;
    DataInputStream din;
    boolean connected = false;
    RaspberryPiApp app;

    public RemoteControlManager(RaspberryPiApp app) {
        try {
            s = new ServerSocket(12345);
        } catch (IOException ex) {
            Logger.getLogger(RemoteControlManager.class.getName()).log(Level.SEVERE, null, ex);
        }

        this.app = app;

        Thread t = new Thread(this);
        t.start();
    }

    public boolean connected() {
        return socket == null ? connected : socket.isConnected();
    }

    @Override
    public void run() {
        while (true) {
            try {
                if (!connected) {
                    socket = s.accept();
                    dout = new DataOutputStream(socket.getOutputStream());
                    din = new DataInputStream(socket.getInputStream());
                    connected = true;
                } else {
//                    dout.writeUTF("heartbeat");
                    String message = din.readUTF();
//                    System.out.println(parse(message));
                    dout.writeUTF(parse(message));
//                    dout.flush();
                }
            } catch (SocketException ex) {
                try {
                    socket.close();
                    din.close();
                    dout.close();
                    socket = null;
                    connected = false;
                } catch (IOException ex1) {
                    Logger.getLogger(RemoteControlManager.class.getName()).log(Level.SEVERE, null, ex1);
                }
            } catch (IOException ex) {
                Logger.getLogger(RemoteControlManager.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    private String parse(String message) {
        message = message.toLowerCase();
        String[] args = message.split(" ");
        switch (args[0]) {
            case "color":
                if (args.length > 1) {
                    switch (args[1]) {
                        case "red":
                            app.color = Color.RED;
                            return "1a";
                        case "green":
                            app.color = Color.GREEN;
                            return "1a";
                        case "blue":
                            app.color = Color.BLUE;
                            return "1a";
                        default:
                            return "!Do not recognize the color: \"" + args[1] + "\".";
                    }
                } else {
                    return "!You must include a color.  Syntax: color [COLOR]";
                }
            default:
                return "!That command is not recognized.  Please check spelling and syntax.  Type \"help\" for help.";
        }
    }
}

桌面代码(缩写):

    public MainGUI() {
        //<editor-fold defaultstate="collapsed" desc=" Center Window to Screen ">
        GraphicsEnvironment g = GraphicsEnvironment.getLocalGraphicsEnvironment();
        GraphicsDevice[] devices = g.getScreenDevices();

        int width = devices[0].getDisplayMode().getWidth();
        int height = devices[0].getDisplayMode().getHeight();

        int w = this.getSize().width;
        int h = this.getSize().height;
        int x = (width - w) / 2;
        int y = (height - h) / 2;
        this.setLocation(x, y);
        //</editor-fold>
        initComponents();
        try {
            socket = new Socket(ip, 12345);
            din = new DataInputStream(socket.getInputStream());
            dout = new DataOutputStream(socket.getOutputStream());
        } catch (UnknownHostException ex) {
            Logger.getLogger(MainGUI.class.getName()).log(Level.SEVERE, null, ex);
        } catch (ConnectException ex) {
            JOptionPane.showMessageDialog(this, "Could not find/connect to a Raspberry Pi at the address: \"" + ip + "\".", "Connection Error", JOptionPane.ERROR_MESSAGE);
            System.exit(0);
        } catch (IOException ex) {
            Logger.getLogger(MainGUI.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

private void jTextField1ActionPerformed(java.awt.event.ActionEvent evt) {                                            
        try {
            dout.writeUTF(jTextField1.getText());
        } catch (IOException ex) {
            Logger.getLogger(MainGUI.class.getName()).log(Level.SEVERE, null, ex);
        }
        jTextField1.setText("");
    } 

@Override
    public void run() {
        while (true) {
            String reply = null;
            try {
                reply = din.readUTF();
                System.out.println(reply);
            } catch (IOException ex) {
                Logger.getLogger(MainGUI.class.getName()).log(Level.SEVERE, null, ex);
            }

            if (reply == null) {
                JOptionPane.showMessageDialog(this, "No reply was recieved from the Raspberry Pi.", "Connection Error", JOptionPane.ERROR_MESSAGE);
            } else if ("heartbeat".equals(reply)){
                // Do nothing.
            } else if ("!".equals(reply.substring(0, 1))) {
                JOptionPane.showMessageDialog(this, reply.substring(1), "Information", JOptionPane.WARNING_MESSAGE);
            }
        }
    }
4

2 回答 2

1

您应该flush()在写入数据后添加一个调用。套接字缓冲数据。

作为使用阻塞套接字流时的一般规则,每个流都需要一个线程。尝试使用单个线程来管理输入和输出流是危险的。

于 2013-11-15T05:21:06.850 回答
0

哇,我真的觉得自己很傻。我忘记在桌面应用程序上启动线程的原因。感谢 jtahlborn 的帮助!

于 2013-11-15T21:00:50.613 回答