通过插座编程报警

时间:2012-03-30 19:39:30

标签: java swing sockets networking

我通过socket编程在j​​ava中制作了数字时钟。

当客户端发送系统服务器的相同时间时匹配时间并播放警报。但是当客户端发送的时间超过1分钟或2分钟时,服务器与系统时间不匹配,并且不播放警报。

这里是我的代码

服务器端:

public class GraphicsServer extends JFrame implements Runnable
{

    String wr;
    String text;
    JTextField f1;
    JTextField f2;
    JScrollPane js;
    JTextArea jt;
    JPanel p;
    Color color;
    Calendar cal;
    String time;
    String time1;
    int hrs;
    int min;
    int sec;

    public GraphicsServer()
    {
        super("Server Tik Tik Tok");
        setSize(400, 400);
        p = new JPanel();
        f1 = new JTextField(10);
        f2 = new JTextField(10);
        p.add(f1);
        p.add(f2);
        add(p);
        Thread thread = new Thread(new Runnable()
        {

            public void run()
            {
                while(true)
                {
                    Calendar now = Calendar.getInstance();
                    int hrs = now.get(Calendar.HOUR_OF_DAY);
                    int min = now.get(Calendar.MINUTE);
                    int sec = now.get(Calendar.SECOND);
                    String time = hrs + ":" + min + ":" + sec;
                    f2.setText(time);
                    time1 = hrs + ":" + min;
                    // System.out.println(time1);
                    // System.out.println(time);
                    try
                    {
                        Thread.sleep(1000);
                    }
                    catch(Exception ee)
                    {
                        System.out.println(ee.getMessage());
                    }
                }
            }
        });
        thread.start();
    }

    public void run()
    {
        try
        {
            ServerSocket server = new ServerSocket(1111);
            while(true)
            {
                Socket ss = server.accept();
                BufferedReader br = new BufferedReader(new InputStreamReader(ss.getInputStream()));
                text = br.readLine();
                f1.setText(text);
                wr = time1;
                if(text.endsWith(wr))
                {
                    color = JColorChooser.showDialog(GraphicsServer.this, "Choose a color", color);
                    p.setBackground(color);
                }
            }
        }
        catch(Exception e)
        {
            System.out.println(e.getMessage());
        }
    }

    public static void main(String[] args)
    {
        GraphicsServer gs = new GraphicsServer();
        gs.setVisible(true);
        Thread th = new Thread(gs);
        th.start();
    }
}

客户端:

public class GrapClient extends JFrame
{

    JButton b1;
    JTextField f1;
    Socket client;

    public GrapClient()
    {
        super("Client Tik Tik Tok");
        setSize(400, 400);
        JPanel p = new JPanel();
        b1 = new JButton("Enter Alarm Time");
        f1 = new JTextField(10);
        p.add(b1);
        p.add(f1);
        add(p);
        ActionListener newListener = new ActionListener()
        {

            public void actionPerformed(ActionEvent event)
            {
                try
                {
                    Socket client = new Socket("localhost", 1111);
                    PrintStream ps = new PrintStream(client.getOutputStream());
                    String g = f1.getText();
                    ps.println(g);
                    f1.setText("");
                }
                catch(Exception e)
                {
                    System.out.println(e.getMessage());
                }
            }
        };
        b1.addActionListener(newListener);
    }

    public static void main(String[] args)
    {
        GrapClient GC = new GrapClient();
        GC.setVisible(true);
        GC.setResizable(false);
    }
}

我想制作闹钟。在服务器中我将数字时钟嵌入到文本字段中。当客户端向服务器发送闹钟时间时,服务器会将客户端闹钟时间与数字时钟时间进行比较。 如果服务器端的时间是23:10并且客户端同时向服务器发送23:10,则服务器将显示jfile chosser。 如果服务器有23:10的时间,客户端发送报警时间23:11。当服务器时间等于1分钟后的客户端报警时间后,服务器将打开jfilechoser。

1 个答案:

答案 0 :(得分:1)

好的,这段代码存在一些问题

  1. 您可以从不同的Thread实例访问许多字段,而无需执行任何同步步骤。这可能会导致奇怪的线程相关错误
  2. 您无法访问Event Dispatch Thread上的Swing组件。阅读Swing Concurrency
  3. 可能是个好主意
  4. 请开始使用体面的变量名称,这样可以更容易地阅读您的代码
  5. 但是,这些都不是真正的问题。问题是你可能认为你的(是的,我重命名了一些变量)

      while ( true ) {
        Socket ss = server.accept();
        BufferedReader br = new BufferedReader( new InputStreamReader( ss.getInputStream() ) );
        String alarmTimeFromSocket = br.readLine();
        alarmTimeTextField.setText( alarmTimeFromSocket );
        if ( alarmTimeFromSocket.endsWith( currentTime ) ) {
          color = JColorChooser.showDialog( GraphicsServer.this, "Choose a color", color );
          contentPane.setBackground( color );
        }
      }
    

    经常运行,但事实并非如此。 br.readLine()电话是阻止电话。因此Thread一直在等待输入。一旦收到新的闹钟时间,它会立即执行下一段代码(比较),然后再次开始等待输入。

    因此,您的比较代码仅在您设置闹钟时间时执行,而不是在时间更新时执行。

    除此之外,我认为endsWith不正确(或者您可能没有设置时间,包括客户端的秒数,在这种情况下它会起作用,但您可以轻松使用equals代替{ {1}})

    问题的一个可能解决方案是在循环中对警报时间和当前挂起时间进行比较,以更新服务器端的挂起时间。但同样,如果另一个endsWith在与壁挂时间更新程序中的墙上时间进行比较的同时更新警报时间字段,您可能会以奇怪的线程问题结束 - Thread