在Java中编写Async(或async like)客户端套接字代码

时间:2010-10-01 05:48:46

标签: java sockets asynchronous

我正在编写一个套接字客户端,用于与网络服务进行交互。目前因为我想支持异步读取和写入,我正在线程输出流和一个套接字的输入流,但我想知道是否有更好的方法来执行此操作。我看过Java NIO并没有留下深刻的印象,我也看了Mina,但是想知道是否有人有更好的想法。

感谢。

2 个答案:

答案 0 :(得分:1)

我用于异步通信的技术是使用ExecutorService。在下面的示例中,服务将执行FutureTask,等待下一行。与此同时,服务器可以继续执行其他任务,并定期轮询读者以查看是否已收到结果。

对于写作,您可以实现类似的FutureTask。

注意:您无需像我一样扩展现有Stream / Reader / Writer的功能。这只是我方便的源代码

 public class SocketStringReader extends BufferedReader {
    /**
     * Internal buffer used for asynchronous reads
     */
    private HashMap<String, String> buf = null;
    /**
     * Waiting status used for asynchronous reads
     */
    private boolean waiting = false;
    /**
     * Shared ExecutorService for asynchronous reads
     */
    private static ExecutorService executor = Executors.newCachedThreadPool();

    /**
     * Constructor here to pacify Java
     * @param in The InputStream to be used as the underlying stream
     */
    public SocketStringReader(InputStream in) {
        super(new InputStreamReader(in));
    }

    @Override
    public HashMap<String, String> readHashMap() throws IOException,
    ClassNotFoundException {
        if (buf != null) {
            HashMap<String, String> resp = new HashMap<String, String>(buf);
            buf = null;
            return resp;
        }
        return stringToHashMap(this.readLine());
    }

    /**
     * Parses a string and converts it to a HashMap
     * @param map A String object of the format "{key=value, key=value, ...}" 
     * that is parsed into a HashMap
     * @return The parsed HashMap
     */
    public static HashMap<String, String> stringToHashMap(String map) {
        // take the string apart
        String[] split = map.split("[={},]");
        HashMap<String, String> result = new HashMap<String, String>();
        for (int i = 1; i < split.length; i += 2) {
            result.put(split[i].trim(), split[i + 1].trim());
        }
        logger.debug("new incoming HashMap: " + result.toString());
        return result;
    }

    /**
     * Returns the availability of the input stream
     * @return The number HashMap objects in the internal buffer
     */
    public int getAvailable() throws IOException {
        return (buf == null) ? 0 : 1;
    }

    @Override
    public HashMap<String, String> readHashMapAsync() throws IOException,
            ClassNotFoundException {
        //Check internal buffer
        if (buf != null) {
            HashMap<String, String> temp = new HashMap<String, String>(buf);
            buf = null;
            return temp;
        } else {
            //Do future crap? or nothing perhaps...
            if (!waiting) {
                waiting = true;
                FutureTask<HashMap<String, String>> future = new FutureTask<HashMap<String, String>>(
                        new Callable<HashMap<String, String>>() {
                            @Override
                            public HashMap<String, String> call() throws Exception {
                                buf = stringToHashMap(readLine());
                                logger.debug("Read object with sessionid: " + buf.get("sessionid"));
                                waiting = false;
                                return null;
                            }
                        });
                executor.execute(future);
            }
        }
        return null;
    }
}

答案 1 :(得分:0)

除了Mina和NIO之外,还有其他一些库(通常都建立在NIO之上)