【问题标题】:Why it warns me the socket is closed when I quit the programme?为什么当我退出程序时它会警告我套接字已关闭?
【发布时间】:2012-03-13 10:10:02
【问题描述】:

这是我的程序,有两个线程,一个是监听用户输入,另一个是套接字:

        bio = new BasicConsoleIO();
        bio.assignObject(worker);

        Thread b = new Thread(bio);
        b.start();

        Thread a = new Thread(worker);
        a.start();

worker是socket,BasicConsoleIO负责监听用户输入 BasicConsoleIO 是这样的:

private Worker worker;
static BufferedReader reader;

@Override
public void run() {
    //......Code Skip......//
    if (inputString.equalsIgnoreCase("q")) {
        this.applicationQuit();
    }
}

public void applicationQuit(){
    this.getWorker().stopWorking();
    System.exit(0);
}

当它按下'q'时,应用程序会调用worker关闭socket,并退出程序,Worker是这样工作的:

private ServerSocket providerSocket;
private Socket socket = null;

int port = 1234;

Worker() {
}

public void stopWorking() {
    System.out.println("worker stop working");

    try {
        if (providerSocket != null) {
            providerSocket.close();
        }
        if (socket != null) {
            socket.close();
        }

    } catch (IOException ioException) {
        ioException.printStackTrace();
    }
}

@Override
public void run() {

    try {
        providerSocket = new ServerSocket(this.port);

        while (true) {
            if (!providerSocket.isClosed()) {

                socket = providerSocket.accept();

                WorkTask wt = new WorkTask();
                wt.setSocket(socket);

                Thread a = new Thread(wt);
                a.start();
            }
        }

    } catch (IOException e) {
        e.printStackTrace();
    }
}

worker 会一直监听请求,并在单独的线程中分配新的工作任务,工作任务的详细信息如下:

Socket socket;
ObjectOutputStream out;
ObjectInputStream in;
Object receivedObj;
String message;

@Override
public void run() {
    try {

        do {
            out.flush();
            receivedObj = in.readObject();

                              //......Code Skip......//

        } while (receivedObj != null
                && !receivedObj.equals(SharedConstant.SOCKET_EOF_STRING));

        if (in != null) {
            in.close();
        }
        if (out != null) {
            out.close();
        }

    } catch (IOException e1) {
        e1.printStackTrace();
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
}

但是当我启动程序并按“q”退出时,它会警告我这个错误:

请分配一个端口号 2333 按 'q' 杀死程序 等待连接: 2333 q worker stop working 无论如何运行我! java.net.SocketException:套接字关闭于 java.net.PlainSocketImpl.socketAccept(本机方法)在 java.net.PlainSocketImpl.accept(PlainSocketImpl.java:408) 在 java.net.ServerSocket.implAccept(ServerSocket.java:462) 在 java.net.ServerSocket.accept(ServerSocket.java:430) 在 com.mydefault.package.Worker.run(Worker.java:61) 在 java.lang.Thread.run(Thread.java:680)

【问题讨论】:

  • 代码太多了!你能把它剪下来只留下相关的部分吗?
  • 我喜欢。比根本不发布代码的人要好得多。

标签: java sockets exception


【解决方案1】:

你可以看到

socket = providerSocket.accept();

正在抛出异常,因为在

public void stopWorking() {
    // Socket won't close unless the user make it to close
    // 4: Closing connection
    System.out.println("worker stop working");

    try {
        if (providerSocket != null) {
            providerSocket.close();

你把它关了。

如果您想避免此错误,我有一个 volatile boolean closed 字段,我将其设置为 true 并在报告错误之前检查。即在我关闭时忽略错误。

【讨论】:

  • 是的,我故意关闭它,但为什么要警告我?我已经得到了一个检查语句 if (!providerSocket.isClosed()) {
  • 当您调用支票时它没有关闭。当您等待接受另一个连接时,它会关闭。 (正如您在堆栈跟踪中看到的那样)
  • 那么,你的意思是关闭函数需要一些时间来关闭它,所以我需要添加一个变量来检查它吗?
  • accept() 需要一些时间作为它的阻塞操作,它可以在那里停留几秒钟、几天、几年。 close() 也需要一些时间(大约一毫秒或更短),但相比之下它是微不足道的。
  • 嗯,似乎很清楚。但是 volatile boolean closed 如何避免问题,我搞不懂。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-30
  • 2021-12-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多