论坛首页 入门讨论版 企业应用

关于java nio的疑惑,帮忙看看

浏览 166 次
该帖已经被评为新手帖
作者 正文
最后更新时间:2008-07-03
最近写了一个memcache协议的分发机制,就是一台机器做代理然后接受memcache协议的命令,然后分发到各个memcache机器。这台代理机器是用java nio写的,可是现在遇到一个问题,就是读数据的时候似乎有时候读不完,就结束了。
下面是代码
public static Command getCommandInstance(SelectionKey key) {
		SocketChannel client = (SocketChannel) key.channel();
		ByteBuffer buffer = (ByteBuffer) key.attachment();

		ByteArrayOutputStream cmdbos = new ByteArrayOutputStream();
		ByteArrayOutputStream databos = new ByteArrayOutputStream();
		boolean eol = false;
		boolean getcommand = false;
		byte b[] = new byte[1];
		try {
			while ((count = client.read(buffer)) > 0) {
				buffer.flip();
				// decoder.detectedCharset();
				// System.out.println(cb.toString());
				while (buffer.hasRemaining()) {
					b[0] = buffer.get();
					// System.out.println(buffer.get());
					if (b[0] == 13) {
						eol = true;

					} else {
						if (eol) {
							eol = false;
							if (b[0] == 10) {
								getcommand = true;
							}
						}
					}
					if (!getcommand){
						cmdbos.write(b, 0, 1);
					}else{
				
						databos.write(b, 0, 1);
					}
				}
				
					buffer.clear();
			}
		} catch (IOException e1) {
			key.cancel();

			try {

				key.channel().close();

			}

			catch (IOException cex) {
			}
		}

		String cmd = cmdbos.toString().trim();

		if (cmd == "") {
			return new BadCommand();
		}

		String[] token = praseCmd(cmd);
		if (token[0].equals("set") && token.length>4) {
			String value = null;
			try {
				value = getValue(databos.toByteArray(),Integer.parseInt(token[4]));
			} catch (NumberFormatException e) {
				// TODO Auto-generated catch block
				return new BadCommand();
			} catch (UnsupportedEncodingException e) {
				// TODO Auto-generated catch block
				return new BadCommand();
			}
			return new SetCommand(token[1], token[2], new Date(Long
					.parseLong(token[3])), Integer.parseInt(token[4]), value);
		}
		
		if (token[0].equals("delete") && token.length>1) {
			Date date = null;
			try {
				if(token.length>2){
					date = new Date(Long.parseLong(token[2]));
				}
			} catch (NumberFormatException e) {
				// TODO Auto-generated catch block
				return new BadCommand();
			}
			return new DeleteCommmand(token[1],date);
		}
		return new BadCommand();
	}


其中cmd是memcache协议的命令行,也就是第一行,cmdbos这个流存的是cmd,读完了cmd以后开始读数据内容,也就是第一行后面的统称为数据内容,databos这个是存数据的,奇怪的问题发生的就是在databos这里,读取cmd的时候没有问题,可是有时候读取databos的时候却发现他是空,不知道为什么会这样,我的客户端发送的请求里面的确有数据,就是用的memcache java客户端发送的。是不是我的判断有问题,判断count>0?因为它是非阻塞的,所以read会马上返回,会不会有时候没有读到东西,但是下一次循环的时候就有东西了,可是如果写成-1,客户端是长连接的话,就会陷入无限循环的地步。
   还望哪位指点一下
   
最后更新时间:2008-07-03
在负载比较大的情况下,read返回0是很正常的现象,注册read事件继续读,也可以采用临时selector注册,强制读完
   
0 请登录后投票
最后更新时间:2008-07-04
为啥要自己控制呢!

http://www.whalin.com/memcached/

不是挺好的么,
   
0 请登录后投票
论坛首页 入门讨论版 企业应用

跳转论坛:
JavaEye推荐