在Java中编写异步(或异步)客户端套接字代码

问题描述:

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

谢谢。

从米娜和NIO

除了有几个其他库(都普遍建立在NIO的顶部)

我用于asynchr的技术onous通信是使用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; 
    } 
}