【问题标题】:How to create a socket that constantly listen from the Server in Java?如何在 Java 中创建一个不断侦听服务器的套接字?
【发布时间】:2023-03-14 22:48:01
【问题描述】:

我正在使用带有 Java 的套接字做一种时钟,但是我需要我的客户端可以与更改时间的服务器交互。我的主要问题是:如果我添加任何代码来监听客户端,服务器就会停止。我想我可以使用线程或异步函数,但我是 Java 的新手,我不知道如何操作它。

这些是我当前的代码:

server.java

import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;

public class server {

public static void main(String[] args) throws IOException,
        ClassNotFoundException {

    ServerSocket ss = new ServerSocket(2000);
    Timer data = new Timer();

    while (true) {

        Socket s = ss.accept();

        ArrayList<Integer> time = new ArrayList<Integer>();

        data.updateTime();

        time.add(data.getHour());
        time.add(data.getMinute());
        time.add(data.getSecond());

        System.out.println(time.get(0) + ":" + time.get(1) + ":"
                + time.get(2));

        try {
            ObjectOutputStream oos = new ObjectOutputStream(
                    s.getOutputStream());
            oos.writeObject(time);
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            Thread.sleep(1000); // 1000 milliseconds is one second.
        } catch (InterruptedException ex) {
            Thread.currentThread().interrupt();
        }
    }
}
}

Timer.java

import java.util.Random;

public class Timer {
private int hour;
private int minute;
private int second;

public Timer() {
    this.hour = randInt(0, 23);
    this.minute = randInt(0, 59);
    this.second = randInt(0, 59);
}

public void changeTime(int hour, int minute, int second) {
    this.hour = hour;
    this.minute = minute;
    this.second = second;
}

public static int randInt(int min, int max) {

    // NOTE: Usually this should be a field rather than a method
    // variable so that it is not re-seeded every call.
    Random rand = new Random();

    // nextInt is normally exclusive of the top value,
    // so add 1 to make it inclusive
    int randomNum = rand.nextInt((max - min) + 1) + min;

    return randomNum;
}

private void updateHour() {
    if (this.hour == 23)
        this.hour = 0;
    else
        this.hour++;
}

private void updateMinute() {
    if (this.minute == 59)
        this.minute = 0;
    else
        this.minute++;
}

private void updateSecond() {
    if (this.second == 59)
        this.second = 0;
    else
        this.second++;
}

public int getHour() {
    return hour;
}

public int getMinute() {
    return minute;
}

public int getSecond() {
    return second;
}

public void updateTime() {
    this.updateSecond();

    if (this.second == 0) {
        this.updateMinute();
        if (this.minute == 0)
            this.updateHour();
    }
}
}

这是我试图发送数据的事件点击:

    public void actionPerformed(ActionEvent arg0) {
    if (arg0.getSource() == startButton) {
        Socket s;
        try {
            s = new Socket("localhost", 2000);
            InputStream in = s.getInputStream();
            OutputStream out = s.getOutputStream();
            BufferedReader br = new BufferedReader(new InputStreamReader(
                    in, textField1.getText()));
            out = new BufferedOutputStream(out);
            PrintWriter pw = new PrintWriter(new OutputStreamWriter(out,
                    textField1.getText()));
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }// we try to connect
    }
}

我想知道你们中是否有人知道我应该在服务器中添加哪种代码以继续发送随机创建的时间并等待是否有来自客户端的任何消息以及是否有消息要更改新的时间。提前感谢您的帮助,如果这是一个基本问题,我很抱歉,但我对 Sockets 和 Java 真的很陌生。

【问题讨论】:

  • 查看 Java 教程的自定义网络部分。

标签: java sockets


【解决方案1】:

您可以创建一个类来存储您的计时器。

public class MyTimer(){
    private Timer t;
    public MyTimer(Timer t){
        this.t = t;
    }

    public synchronized Timer getTimer(){
        return t;
    }

    public synchronized void setTimer(Timer t){
        this.t = t;
    }
}

而在服务器中,你需要使用这个类中的一个对象。

final MyTimer myTimer = new MyTimer(new Timer());

在 while 循环的第一行,您可以将 myTimer 中的计时器获取到您的数据变量中。

Timer data = myTimer.getTimer();

在while循环之前,启动一个新的线程来监听客户端,这样就可以更新myTimer对象中的定时器了。

new Thread(new Runnable(){
    public void run(){
        while(true){
            //Listen to the client if there is new time available
            //get new timer to a variable (here, newData)
            myTimer.setTimer(newData);
        }
    }
}).start();

【讨论】:

  • 嗨,@Ramesh-X,我做了这个改变,因为我以为你告诉我的,它没有工作,因为服务器没有向我发送任何信息,当我尝试发送静态值时就像在事件中也没有工作一样。 server.java pastebin.com/5drzwF6z event pastebin.com/gQA0R85b event error java.io.UnsupportedEncodingException
  • 在一个线程中读取部分并在另一个线程中写入部分。您已经在同一个线程中完成了这两件事。认为,一个线程总是发送定时器,不在乎阅读。而其他线程只读取Timer,不关心写Timer..
  • 在这个新版本中,我认为我更改为一个新线程,pastebin.com/8NLmxPxR 因为如果我从客户端发送某些内容,它有时可能会停止一秒钟,它会给我一个奇怪的错误(知道我'我只是想发送一些数据),这是新事件:pastebin.com/WpGAeHNK 但最后它给了我这个错误:java.net.SocketException:软件导致连接中止:java.net.SocketOutputStream.socketWrite0 处的套接字写入错误(Native Method) at java.net.SocketOutputStream.socketWrite(Unknown Source) 感谢您的帮助:)
  • 非常感谢!这是我的一个愚蠢的错误!
猜你喜欢
  • 2017-07-20
  • 2017-07-03
  • 1970-01-01
  • 2012-07-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多