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