2010-04-27 65 views
2

我在Java的新,所以請原諒任何淫穢的錯誤,我可以做:)問題與封閉的網絡任務

我正在開發在Java程序,除其他事項外,還應當辦理客戶端會連接到服務器。該服務器有3個線程中運行,並且我在下面的方式創造了他們:

DaemonForUI du; 
DaemonForPort da; 
DaemonForCheck dc; 

da = new DaemonForPort(3); 
dc = new DaemonForCheck(5); 
du = new DaemonForUI(7); 

Thread t_port = new Thread(da); 
Thread t_check = new Thread(dc); 
Thread t_ui = new Thread(du); 

t_port.setName("v1.9--PORTd"); 
t_check.setName("v1.9-CHECKd"); 
t_ui.setName("v1.9----UId"); 

t_port.start(); 
t_check.start(); 
t_ui.start(); 

每個線程處理的完整程序的不同方面。線程t_ui負責接受來自客戶端的異步傳入連接,處理髮送的數據並將其他數據發送回客戶端。當我從前一段代碼中刪除所有必須使用t_ui線程的命令時,一切運行正常,在我的情況下意味着其他線程正在打印它們的調試消息。

如果我設置t_ui線程也運行,那麼整個程序將阻塞t_ui線程的「接受」。

在聯機手冊,看完後我看到,接受的連接應該是非阻塞的,因此使用這樣的事情:

public ServerSocketChannel ssc = null; 

ssc = ServerSocketChannel.open(); 
ssc.socket().bind(new InetSocketAddress(port)); 
ssc.configureBlocking(false); 

SocketChannel sc = ssc.accept(); 

if (sc == null) { 
    ; 
} 
else { 
    System.out.println("The server and client are connected!"); 
    System.out.println("Incoming connection from: " + sc.socket().getRemoteSocketAddress()); 
    in = new DataInputStream(new BufferedInputStream(sc.socket().getInputStream())); 
    out = new DataOutputStream(new BufferedOutputStream(sc.socket().getOutputStream())); 
    //other magic things take place after that point... 

爲t_ui的線程創建如下:

class DaemonForUI implements Runnable{ 
    private int cnt; 
    private int rr; 
    public ListenerForUI serverListener; 

    public DaemonForUI(int rr){ 
     cnt = 0; 
     this.rr = rr; 
     serverListener = new ListenerForUI(); 
    } 

    public static String getCurrentTime() { 
     final String DATE_FORMAT_NOW = "yyyy-MM-dd HH:mm:ss"; 
     Calendar cal = Calendar.getInstance(); 
     SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT_NOW); 
     return (sdf.format(cal.getTime())); 
    } 


    public void run() { 
     while(true) { 
      System.out.println(Thread.currentThread().getName() + "\t (" + cnt + ")\t (every " + rr + " sec) @ " + getCurrentTime()); 
      try{ 
       Thread.sleep(rr * 1000); 
       cnt++; 
      } 
      catch (InterruptedException e){ 
       e.printStackTrace(); 
      } 
     } 
    } 
} 

顯然,我在創建套接字或使用線程時做了錯誤的事情。你知道是什麼導致了這個問題?

每一個幫助將不勝感激。

+0

你可以在ssc.accept()之後加入某種調試語句,並告訴我們它是否可以被打?看看代碼它看起來不像接受應該阻止...請驗證它實際上阻止接受,而不是其他放在你的代碼中。 – Kiril 2010-04-27 16:51:31

回答

1

直到您知道需要它時才使用非阻塞I/O。只需爲每個接受的套接字啓動一個新線程,併爲接受線程啓動一個新線程。

0

問題解決了:) 我看了你的建議,仔細看了看代碼。這是一個設計錯誤,因爲我有一個函數在DaemonForUI的構造函數(更具體地說是在ListenerForUI()內部)中創建了一個while(true)循環。它導致整個程序在while語句中循環,因此拖延了所有其他操作。

愚蠢的錯誤,我必須承認... :(

感謝所有幫助大家回答我的問題。

我會考慮每一個傳入的連接創建一個新的線程所提到的概念。該對於每個傳入連接必須執行的任務並不是那麼重,所以我認爲只有一個線程可以完成這項工作。