停止 ServerSocket Accept() 循环线程

发布于 2024-11-01 05:23:18 字数 2600 浏览 0 评论 0原文

我正在实现一个非常基本的 API,以便更好地控制 ServerSocket 和 Sockets,但我遇到了一个非常奇怪的问题,由于缺乏线程知识,我无法修复该问题。让我解释一下。

在我的 SocketStreamReceiver 类中,我使用辅助线程通过 ServerSocket#accept() 来侦听新套接字。有 2 个方法:start() 和 stop(),客户端可以使用它们来启动(创建线程并开始使用 accept() 进行侦听)和停止(关闭 ServerSocket 并销毁线程) SocketStreamReceiver。

如何实现 stop() 方法?请记住,stop() 可以在 doSomething() 内部调用,在 start() 启动的同一个辅助线程中。您可以更改任何您想要的内容:如果需要,您可以在线程内创建 ServerSocket,就在 while(running) 之前。

public class SocketStreamReceiver{
    ...
    private Thread thread;
    private ServerSocket server;
    private boolean running;
    ...

    public void start () throws IOException{
        if (thread != null) return;

        server = new ServerSocket (port);
        thread = new Thread (new Runnable (){
            @Override
            public void run (){
                try{
                    while (running){
                        Socket socket = server.accept ();
                        doSomething (socket);
                    }
                }catch (SocketException e){
                    ...
                }catch (IOException e){
                    ...
                }
            }
        }, "SocketStreamReceiver");
        thread.start ();
    }

    public void stop () throws IOException{
        if (thread == null) return;

        //code...

        thread = null;
    }
}

谢谢。

编辑 - 解决方案:

public class SocketStreamReceiver{
    private Thread thread;
    private ServerSocket server;
    private volatile boolean running;
    ...

    public synchronized void start () throws IOException{
        if (thread != null) throw new IllegalStateException ("The receiver is already started.");

        server = new ServerSocket (port);
        thread = new Thread (new Runnable (){
            @Override
            public void run (){
                try{
                    running = true;
                    while (running){
                        doSomething (server.accept ());
                        ...
                    }
                }catch (SocketException e){
                    ...
                }catch (IOException e){
                    ...
                }
            }
        }, "SocketStreamReceiver");
        thread.start ();
    }

    public synchronized void stop (){
        if (thread == null) return;

        running = false;
        try{
            if (server != null){
                server.close ();
            }
        }catch (IOException e){}

        thread = null;
    }
}

I'm implementing a very basic API to have a better control over ServerSocket and Sockets, but I'm in a very weird problem that I cannot fix due to my lack of threads knowledge. Let me explain it.

In my class SocketStreamReceiver I use a secondary thread to listen for new sockets with ServerSocket#accept(). There are 2 methods: start() and stop() that the client can use to start (creating a thread and begin listening with accept()) and stop (closing the ServerSocket and destroying the thread) my SocketStreamReceiver.

How will you implement stop() method? Keep in mind that stop() can be called inside doSomething(), in the same secondary thread started by start(). You can change anything you want: you can create the ServerSocket inside the thread if you want, just before while(running).

public class SocketStreamReceiver{
    ...
    private Thread thread;
    private ServerSocket server;
    private boolean running;
    ...

    public void start () throws IOException{
        if (thread != null) return;

        server = new ServerSocket (port);
        thread = new Thread (new Runnable (){
            @Override
            public void run (){
                try{
                    while (running){
                        Socket socket = server.accept ();
                        doSomething (socket);
                    }
                }catch (SocketException e){
                    ...
                }catch (IOException e){
                    ...
                }
            }
        }, "SocketStreamReceiver");
        thread.start ();
    }

    public void stop () throws IOException{
        if (thread == null) return;

        //code...

        thread = null;
    }
}

Thanks.

EDIT - Solution:

public class SocketStreamReceiver{
    private Thread thread;
    private ServerSocket server;
    private volatile boolean running;
    ...

    public synchronized void start () throws IOException{
        if (thread != null) throw new IllegalStateException ("The receiver is already started.");

        server = new ServerSocket (port);
        thread = new Thread (new Runnable (){
            @Override
            public void run (){
                try{
                    running = true;
                    while (running){
                        doSomething (server.accept ());
                        ...
                    }
                }catch (SocketException e){
                    ...
                }catch (IOException e){
                    ...
                }
            }
        }, "SocketStreamReceiver");
        thread.start ();
    }

    public synchronized void stop (){
        if (thread == null) return;

        running = false;
        try{
            if (server != null){
                server.close ();
            }
        }catch (IOException e){}

        thread = null;
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

浮生未歇 2024-11-08 05:23:18

我会这样做

public void stop() {
    running = false;
    try{
        if (server != null) server.close ();
    } catch (IOException ignored){
    }
}

似乎你甚至不需要运行标志。不过,我会在您的服务器接受代码中使用它来确定是否需要异常。即当运行 == false 时忽略所有异常。

我会让 running 变得不稳定。

如果您可以从不同的线程运行它们,我将使 start()/stop() 同步。

I would just do

public void stop() {
    running = false;
    try{
        if (server != null) server.close ();
    } catch (IOException ignored){
    }
}

It doesn't appear you even need the running flag. However I would use it in your server accept code to determine if an Exception is expected or not. i.e. when running == false ignore all exceptions.

I would make running volatile.

I would make start()/stop() synchronized if you can run these from different threads.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文