2013-02-11 113 views
0

我有一個UDP服務器類實現Runnable接口。我在線程中啓動它。 問題是我無法阻止它。即使在調試中,它也會停止在pt.join()方法中。停止線程與udp服務器

這裏是我的服務器類

import java.io.IOException; 
import java.net.DatagramPacket; 
import java.net.DatagramSocket; 
import java.net.SocketException; 


public class Network implements Runnable { 
final int port = 6789; 

DatagramSocket socket; 

byte[] input = new byte[1024]; 
byte[] output = new byte[1024]; 

public Network() throws SocketException{ 
    socket = new DatagramSocket(6789); 
} 

@Override 
public void run() { 
    while(true){ 
     DatagramPacket pack = new DatagramPacket(input,input.length); 
     try { 
      socket.receive(pack); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     input = pack.getData(); 
     System.out.println(new String(input)); 
     output = "Server answer".getBytes(); 
     DatagramPacket sendpack = new DatagramPacket(output,output.length,pack.getAddress(),pack.getPort()); 
     try { 
      socket.send(sendpack); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 
} 
} 

這是主類

public class Main { 

static Network network = null; 

public static void main(String[] args) throws IOException{ 
    network = new Network(); 
    System.out.println("Try to start server"); 
    Thread pt = new Thread(network); 
    pt.start(); 

    pt.interrupt(); 
    try { 
     pt.join(); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 

    System.out.println("Stop server"); 
} 
} 

如何停止服務器?

回答

2

java.net的讀取是不可中斷的。您必須關閉DatagramSocket或使用超時(setSoTimeout())讀取它,並在得到結果SocketTimeoutException時檢查中斷狀態:如果設置,則退出線程。

+0

+1如果在接收過程中關閉套接字,你應該會得到'IOException'。 – Gray 2013-02-11 23:56:50

+0

@Gray更正,實際上它是一個'java.net.SocketException:socket closed'。 – EJP 2013-02-12 00:03:20

1

調用interrupt並不實際停止線程,它只是設置一個標誌。

在你的循環中,檢查isInterrupted()。例如,快速和骯髒的方式將是變化

while(true) 
to 
while (!Thread.currentThread().isInterrupted()) 

但是,如果你對這個項目更認真,你應該諮詢一些更多的文檔。

正如@EJP所述,如果掛在Socket IO中,則需要關閉套接字或超時。

+0

..或發送一個本地堆棧UDP消息來解除阻止它。 – 2013-02-12 00:42:37

1

除了EJP說的,你可能應該有一個名爲running(或其他)的本地布爾值,並且在你輸入while循環之前將它設置爲true。讓你的w​​hile循環以這個本地布爾值爲條件。並提供方法(stopServer()和isRunning())來設置和檢查布爾的狀態。你也可能希望從while循環中刪除try-catch,並將整個while循環放在try-catch-finally中,並在finally語句中執行清理(set running = false;關閉連接等)

+0

雖然這個工作,我更喜歡'isInterrupted()'因爲它涵蓋了更多的情況下,使用執行者等... – user949300 2013-02-11 23:50:03