套接字不发送数据

时间:2013-11-15 02:35:12

标签: java sockets

我似乎在这里遗漏了一些小事。我正在使用java为raspberry pi和桌面命令行编写应用程序。我可以将数据发送到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);
            }
        }
    }

2 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:0)

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