有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如果要打开socket,如何中断线程?

我已尝试关闭作为多线程服务器一部分的当前线程。 线程已准备好打开客户端可能访问的socket

除非下面的代码包含在while()循环中,否则一切正常

new ServerThread(serversocket.accept(), this.Rstr, bag.numberofDatatoAcquire).start();

以下是服务器的代码:

public void run() {

    System.out.println("This has been called ");   

    try{

       System.out.println("This has been tried");    
       serversocket = new ServerSocket(this.iPort);                                 

       Thread thisThread = Thread.currentThread();

       while(!thisThread.isInterrupted()){
           new ServerThread(serversocket.accept(), this.Rstr, bag.numberofDatatoAcquire).start();
           //sending socket accessed, where it will store the data and how much it will collect it.                            
           System.out.println("This has been running");                  
           Thread.sleep(10);               
       }           
    }catch(InterruptedException e){
        //why bother? it is an usual happening...lol
    }catch(IOException ioe)
    {
        System.err.println("Can't open the socket on port");               
    }
    finally{     
       System.out.println("Thread is dead and ready for change");
    }
}

这是GUI事件的一部分:这在没有“新服务器线程…”的情况下运行良好代码

private OverWatch EW = new OverWatch(bag.iPortOrder, bag.SessionAcquisitionSavingDirectory);   

....

private void OverWatcherControl(boolean checker)
{
    if(checker)
        EW.start();  
    else
        EW.interrupt();

}

因为变数包。numberofDataToAcquire(公共整数类型)应该在用户需要时更改,我想我必须停止此线程并更改变量,然后再次运行此线程。我错了吗?或者我怎样才能打断这条线

谢谢


共 (3) 个答案

  1. # 1 楼答案

    我最初用serverSocket.setSoTimeout(millis)SocketTimeoutException来回答这个问题。见下文

    更好的方法是使用ServerSocketChannel,当您调用thread.interrupt()accept()调用会中断ServerSocketChannel,因此您根本不需要旋转。所以你会做一些类似的事情:

    ServerSocketChannel socketChannel = ServerSocketChannel.open();
    socketChannel.socket().bind(new InetSocketAddress(this.iPort), 10);
    ...
    while (! thisThread.isInterrupted()) {
        // channel accepts _are_ interrupted by the call to thread.interrupt()
        // it throws ClosedByInterruptException when interrupt() is called
        SocketChannel accepted = socketChannel.accept();
        new ServerThread(accepted.socket(), this.Rstr,
            bag.numberofDatatoAcquire).start();
    }
    

    我将努力解释代码:

    while(!thisThread.isInterrupted()){
       new ServerThread(serversocket.accept(), this.Rstr,
            bag.numberofDatatoAcquire).start();
       Thread.sleep(10);               
    }           
    

    我认为您这里的问题是serversocket.accept()挂起等待接受套接字。从^{} javadocs开始:

    Listens for a connection to be made to this socket and accepts it. The method blocks until a connection is made.

    您需要在while循环之前设置套接字超时。你可以用^{}来做这个

    serversocket.setSoTimeout(10000);
    

    如果超时,则会抛出SocketTimeoutException。那么您就不需要Thread.sleep(10)(顺便说一句,这是10毫秒),因为睡眠将在accept()方法中完成。我不推荐accept(10),因为那会非常激进

  2. # 2 楼答案

    正如使用超时或终止套接字的替代方法

    到套接字的新连接。这将“唤醒”accept(),然后可以使用额外的信号机制(例如,标志或中断检查)(尽管逻辑必须在println中稍微从显示更改为不“存在”)

    我以前使用过这种方法,它工作得很好:不需要等待超时(即使是排序)或处理另一个异常,套接字保持打开/有效(这可能是需要的,也可能不是需要的)。另一方面,我不确定长时间/中断的TCP握手会发生什么,但我从未遇到过这种情况;-)

    快乐编码

  3. # 3 楼答案

    ServerSocket.accept()是对线程中断不响应的阻塞调用。几乎所有的java.net阻塞调用(连接、读取、接受等)都不响应线程。中断()。这种行为是“按设计的”

    唤醒.accept().read()中阻塞的线程的一种方法是关闭底层套接字

    或者,您可以在ServerSocket上设置SO_超时(setSoTimeout),这将导致.accept()通过抛出SocketTimeoutException定期唤醒。您可以捕获该异常并将其用作检查线程中断状态的机会

    {}包(java1.4+)提供了一个对中断更敏感的替代套接字API