阻止网络任务出现问题

时间:2010-04-27 15:05:09

标签: java multithreading network-programming

我是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();
            }
        }
    }
}

显然,我在创建套接字或使用线程时做错了。你知道造成这个问题的原因吗?

非常感谢每一位帮助。

2 个答案:

答案 0 :(得分:1)

在您知道需要之前,请勿使用非阻塞I / O.只需为每个接受的套接字以及接受线程启动一个新线程。

答案 1 :(得分:0)

问题解决了:) 我看了你的建议,仔细看了一下代码。这是一个设计错误,因为我有一个函数在DaemonForUI的构造函数中创建了一个while(true)循环(更具体地说,在ListenerForUI()内部)。它导致整个程序在while语句中循环,因此停止了所有其他操作。

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

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

我将考虑为每个传入连接创建新线程的提到的想法。必须为每个传入连接执行的任务不是那么重,所以我认为一个单独的线程可以完成这项工作。