用Java编写异步(或类似异步)客户机套接字代码

用Java编写异步(或类似异步)客户机套接字代码,java,sockets,asynchronous,Java,Sockets,Asynchronous,我正在编写一个用于与网络服务交互的套接字客户端。目前,因为我想支持异步读写,所以我正在对一个套接字的输出流和输入流进行线程处理,但我想知道是否有更好的方法来实现这一点。我看过JavaNIO,并没有留下深刻的印象,我也看过Mina,但想知道是否有人有更好的想法 谢谢。除了Mina和NIO之外,还有其他几个库(都是在NIO之上构建的) JDK 7还增加了对 除了Mina和NIO之外,还有一些其他库(通常都构建在NIO之上) JDK 7还增加了对 我用于异步通信的技术是使用Execut

我正在编写一个用于与网络服务交互的套接字客户端。目前,因为我想支持异步读写,所以我正在对一个套接字的输出流和输入流进行线程处理,但我想知道是否有更好的方法来实现这一点。我看过JavaNIO,并没有留下深刻的印象,我也看过Mina,但想知道是否有人有更好的想法


谢谢。

除了Mina和NIO之外,还有其他几个库(都是在NIO之上构建的)

  • JDK 7还增加了对

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

  • JDK 7还增加了对

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

      对于写作,您可以实现类似的未来任务

      注意:您不需要像我那样扩展现有流/读/写器的功能。这只是我手头的源代码

      公共类SocketStringReader扩展了BufferedReader{
      /**
      *用于异步读取的内部缓冲区
      */
      私有HashMap buf=null;
      /**
      *用于异步读取的等待状态
      */
      私有布尔等待=false;
      /**
      *异步读取的共享执行器服务
      */
      私有静态ExecutorService executor=Executors.newCachedThreadPool();
      /**
      *构造函数来安抚Java
      *要用作基础流的InputStream中的@param
      */
      公共SocketStringReader(输入流输入){
      超级(新输入流阅读器(in));
      }
      @凌驾
      public HashMap readHashMap()引发IOException,
      ClassNotFoundException{
      如果(buf!=null){
      HashMap resp=新的HashMap(buf);
      buf=null;
      返回响应;
      }
      返回stringToHashMap(this.readLine());
      }
      /**
      *解析字符串并将其转换为哈希映射
      *@param映射格式为“{key=value,key=value,…}”的字符串对象
      *它被解析为一个HashMap
      *@返回已解析的HashMap
      */
      公共静态HashMap stringToHashMap(字符串映射){
      //把绳子拆开
      字符串[]split=map.split([={},]');
      HashMap结果=新建HashMap();
      对于(int i=1;i
      我用于异步通信的技术是使用ExecutorService。在我下面的示例中,服务将执行一个FutureTask,它将等待下一行。同时,服务器可以继续执行其他任务,并定期轮询读取器以查看是否收到结果

      对于写作,您可以实现类似的未来任务

      注意:您不需要像我那样扩展现有流/读/写器的功能。这只是我手头的源代码

      公共类SocketStringReader扩展了BufferedReader{
      /**
      *用于异步读取的内部缓冲区
      */
      私有HashMap buf=null;
      /**
      *用于异步读取的等待状态
      */
      私有布尔等待=false;
      /**
      *异步读取的共享执行器服务
      */
      私有静态ExecutorService executor=Executors.newCachedThreadPool();
      /**
      *构造函数来安抚Java
      *要用作基础流的InputStream中的@param
      */
      公共SocketStringReader(输入流输入){
      超级(新输入流阅读器(in));
      }
      @凌驾
      public HashMap readHashMap()引发IOException,
      ClassNotFoundException{
      如果(buf!=null){
      HashMap resp=新的HashMap(buf);
      buf=null;
      返回响应;
      }
      返回stringToHashMap(this.readLine());
      }
      /**
      *解析字符串并将其转换为哈希映射
      *@param映射格式为“{key=value,key=value,…}”的字符串对象
      *它被解析为一个HashMap
      *@返回已解析的HashMap
      */
      公共静态HashMap stringToHashMap(字符串映射){
      //把绳子拆开
      字符串[]split=map.split([={},]');
      HashMap结果=新建HashMap();
      
       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;
          }
      }