2010-04-27 41 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语句中循环,因此拖延了所有其他操作。

愚蠢的错误,我必须承认... :(

感谢所有帮助大家回答我的问题。

我会考虑每一个传入的连接创建一个新的线程所提到的概念。该对于每个传入连接必须执行的任务并不是那么重,所以我认为只有一个线程可以完成这项工作。