`
wjjxf
  • 浏览: 239896 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

JavaNIO开发的猜大小游戏

阅读更多
学习一下javaNIO用法,就开发了个简单的小游戏,猜大小,服务端用javaNIO api写的,客户端用的普通的socket,一个服务端支持多个客户端!每个客户端猜大还是小,然后由管理员控制开始猜测然后通知所有玩家。。。使用NIO传送数据,ByteBuffer需要用characterEncoding编码才行,要不然对方收不到。
这是服务端代码:
 
package game;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Random;

/**
 *  服务端
 * @version 1.0 2011-4-27 
 */
public class BigSmallServer {
	protected Charset charset = Charset.forName("UTF-8");
	protected CharsetEncoder charsetEncoder = charset.newEncoder();
	protected CharsetDecoder charsetDecoder = charset.newDecoder();
	private Selector selector = null;
	List<Player> players = new ArrayList<Player>();
	public static void main(String[] args) throws Exception{
		new BigSmallServer().run();
	}
	public void print(Object o){
		System.out.println(new Date().toLocaleString()+":"+o);
	}
	public void run() throws Exception{
		selector = Selector.open();
		ServerSocketChannel ssc = ServerSocketChannel.open();
		ServerSocket serverSocket = ssc.socket();
		serverSocket.bind(new InetSocketAddress(8888));
        ssc.configureBlocking(false);
        ssc.register(selector, SelectionKey.OP_ACCEPT);
        
        while(true){
        	int nKeys = selector.select();
        	if(nKeys > 0){
        		 Iterator<SelectionKey> it = selector.selectedKeys().iterator();
        		 while(it.hasNext()){
        			 SelectionKey key = it.next();
        			 if(key.isAcceptable()){
        				 ServerSocketChannel server = (ServerSocketChannel) key.channel();
                         SocketChannel channel = server.accept();
                         if (channel == null) {
                             continue;
                         }
                         channel.configureBlocking(false);
                         channel.register(selector, SelectionKey.OP_READ);
                         print("客户端:"+channel.socket().getRemoteSocketAddress()+" 建立连接...");          
                         Player player = new Player();
                         player.id = channel.socket().getRemoteSocketAddress().toString();
                         player.sc = channel;
                         players.add(player);
        			 }
        			 if(key.isReadable() ){
        				 this.readDataFromSocket(key);
        			 } 
        			 it.remove();
        		 }//end while
        	}//end if
        }//end while
	}
	
	private void readDataFromSocket(SelectionKey key) throws IOException {
		
        ByteBuffer buf = ByteBuffer.allocate(1024);
        SocketChannel sc = (SocketChannel) key.channel();
        print("客户端:"+sc.socket().getRemoteSocketAddress()+" 读取数据...");    
        Player player = null;
		for(Player p: players){
			if(p.id.equals(sc.socket().getRemoteSocketAddress().toString()))
			{
				player = p;break;
			}
		}
        int readBytes = 0;
        int ret;

        try { 
            while ((ret = sc.read(buf)) > 0) {
                readBytes += ret;
            }
            if(readBytes <= 0){
            	sc.close();
            }
        } finally {
            buf.flip();
        }
 
//        String s = new String(buf.array());
//        System.out.println(sb.toString());
        String msg = charsetDecoder.decode(buf).toString();
        String[] cmds = msg.split(":");
        String cmd = cmds[0];
        if("name".equals(cmd)){
        	player.name = cmds[1];
        	if(player.name.equals("admin")){
        		player.bAdmin = true;
        	} 
        	sc.write(charsetEncoder.encode(CharBuffer.wrap( "ok:"+player.bAdmin  + "\n")));        	
        	print(player.id+" 昵称:"+player.name);
        }
        if("guess".equals(cmd)){
        	//得到猜测数据
        	player.guess = cmds[1].charAt(0); 
        	sc.write(charsetEncoder.encode(CharBuffer.wrap( "guessok\n")));
        	print(player.name+" 猜测:" + player.guess);
        	//通知管理员有多少个人猜测了 
        }
        if("start".equals(cmd)){
        	//开始,所有的guess设置为空
        	if(player.bAdmin){
        		//通知所有客户端可以开始了 
	        	for(Player p: players){ 
	        		if(p.bAdmin)continue;//管理员不玩
	        		p.guess = 0;
	        		p.sc.write(charsetEncoder.encode(CharBuffer.wrap("start\n")));
	    		}
        	}
        }
        if("result".equals(cmd)){
        	//得结果通知所有人
        	if(player.bAdmin){
        		float f = 0.5000F;//大的概率
        		boolean rs = this.getTrueFalse(f);				
				 
        		String res = "";
        		int cWin = 0, cLoss = 0;
        		for(Player p: players){
	        		if(p.bAdmin)continue;//管理员不玩
	        		if(rs && p.guess == 'b'){
						cWin++;
					}else if(!rs && p.guess == 's'){
						cWin++;
					}else{
						cLoss++;
					}  
	    		}
        		
	        	for(Player p: players){
	        		if(p.bAdmin)continue;//管理员不玩
	        		if(rs && p.guess == 'b'){
						res ="result:胜利,结果为大,积分="+(++p.score)+",本局赢/输的人数为:"+cWin+"/"+cLoss;
					}else if(!rs && p.guess == 's'){
						res ="result:胜利,结果为小,积分="+(++p.score)+",本局赢/输的人数为:"+cWin+"/"+cLoss;
					}else{
						res ="result:失败,结果为"+(rs?"大":"小")+",积分="+(--p.score)+",本局赢/输的人数为:"+cWin+"/"+cLoss;
					} 
	        		p.sc.write(charsetEncoder.encode(CharBuffer.wrap( res+"\n")));
	    		}
        	}
        }
        // process buffer
        // buf.clear();
        
    }
	/**
	 * 以rand的概率返回true
	 * rand范围是0.01%-99.99%。即0.0001-0.9999
	 */
	public  boolean getTrueFalse(float r){
		Random rand  = new Random();
		int v = (int) (r * 10000);
		if(v < 0 || v > 10000)throw new RuntimeException("out of range");
		rand.setSeed(System.nanoTime()+v);		
		int r1 = rand.nextInt(10000) + v;
		return r1 - 10000 >=0 ?true:false; 
	}
	static class Player{
		public String name;
		public String id;
		public int score;
		public boolean bAdmin;//只有管理员有权限决定开始
		public char guess;//猜测的大小
		public SocketChannel sc;//
	} 
}


这是客户端代码:
 
package game;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.util.Date;

/**
 * 客户端
 * @version 1.0 2011-4-27 
 */
public class BigSmallClient {
	public void print(Object o){
		System.out.println(new Date().toLocaleString()+":"+o);
	}
	public static void main(String[] args) throws Exception{
		new BigSmallClient().run();
	}
	
	public void run()throws Exception{
		Socket s = new Socket("172.16.1.134", 8888);
		print("连接服务器成功..."+s.getRemoteSocketAddress().toString());
		print("请输入大名:");
		InputStream  ins = s.getInputStream();
		BufferedReader sbr = new BufferedReader(new InputStreamReader(ins));
		BufferedReader inbr = new BufferedReader(new InputStreamReader(System.in));
		OutputStream os = s.getOutputStream();
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os));
		String line = inbr.readLine();
		bw.write("name:"+line);
		bw.flush();
		line = sbr.readLine();
		String[] cmds = line.split(":");
		if(cmds[0].equals("ok")){
			if("true".equals(cmds[1])){
				while(true){
					print("输入命令(start,result)...");
					line = inbr.readLine();
					if("start".equals(line)){
						bw.write("start");
						bw.flush();
					}else if("result".equals(line)){
						bw.write("result");
						bw.flush();
					}else if("q".equals(line)){
						break;
					}
				}
			}else{
				print("设置成功,请等待开始...");
				line = sbr.readLine();
				do{
					cmds = line.split(":");
					if(cmds[0].equals("start")){
						print("可以开始了,大(b),小(s),退出(q)?");
						line = inbr.readLine();
						if(line.equals("q"))break;
						bw.write("guess:"+line);
						bw.flush();
						line = sbr.readLine();
						continue;
					}
					if(cmds[0].equals("guessok")){
						print("猜测成功,等待结果...");
						line = sbr.readLine();
						continue;
					}
					if(cmds[0].equals("result")){ 
						print("结果:"+cmds[1]);
						line = sbr.readLine();
						continue;
					}
				}while(true);
			}
		}
		 
		s.close(); 
	}

}


分享到:
评论

相关推荐

    基于Java NIO实现五子棋游戏.zip

    基于Java NIO实现五子棋游戏.zip基于Java NIO实现五子棋游戏.zip 基于Java NIO实现五子棋游戏.zip基于Java NIO实现五子棋游戏.zip 基于Java NIO实现五子棋游戏.zip基于Java NIO实现五子棋游戏.zip 基于Java NIO实现...

    JavaNIO chm帮助文档

    Java NIO系列教程(一) Java NIO 概述 Java NIO系列教程(二) Channel Java NIO系列教程(三) Buffer Java NIO系列教程(四) Scatter/Gather Java NIO系列教程(五) 通道之间的数据传输 Java NIO系列教程(六)...

    java NIO和java并发编程的书籍

    java NIO和java并发编程的书籍java NIO和java并发编程的书籍java NIO和java并发编程的书籍java NIO和java并发编程的书籍java NIO和java并发编程的书籍java NIO和java并发编程的书籍java NIO和java并发编程的书籍java...

    Java NIO英文高清原版

    Java NIO,全称为Non-Blocking Input/Output(非阻塞输入/输出),是Java平台中用于替代标准I/O(BIO)模型的一种新机制。NIO在Java 1.4版本引入,提供了更高效的数据处理和通道通信方式,特别适用于高并发、大数据...

    Java视频教程 Java游戏服务器端开发 Netty NIO AIO Mina视频教程

    jaca视频教程 jaca游戏服务器端开发 Netty NIO AIO Mina视频教程 课程目录: 一、Netty快速入门教程 01、第一课NIO 02、第二课netty服务端 03、第三课netty客户端 04、第四课netty线程模型源码分析(一) 05、...

    java NIO.zip

    Java NIO,全称为Non-...总的来说,Java NIO提供了比传统I/O更灵活、更高效的数据传输机制,尤其适用于需要处理大量并发连接的网络应用,如服务器端的开发。通过合理利用NIO的特性,可以构建出高性能、低延迟的系统。

    java NIO 中文开发文档

    在学习Java NIO时,这份中文开发文档最全版.pdf将涵盖这些核心概念的详细解释、示例代码以及最佳实践,帮助读者掌握如何在实际项目中应用NIO。对于初学者来说,深入理解这些内容,将有助于构建高效、可扩展的Java...

    java NIO 视频教程

    Java NIO(New IO)是一个可以替代标准Java IO API的IO API(从Java 1.4开始),Java NIO提供了与标准IO不同的IO工作方式。 Java NIO: Channels and Buffers(通道和缓冲区) 标准的IO基于字节流和字符流进行操作的,...

    Java NIO 中文 Java NIO 中文 Java NIO 中文文档

    Java NIO 深入探讨了 1.4 版的 I/O 新特性,并告诉您如何使用这些特性来极大地提升您所写的 Java 代码的执行效率。这本小册子就程序员所面临的有代表性的 I/O 问题作了详尽阐述,并讲解了 如何才能充分利用新的 I/O ...

    Java NIO实战开发多人聊天室

    01-Java NIO-课程简介.mp4 05-Java NIO-Channel-FileChannel详解(一).mp4 06-Java NIO-Channel-FileChannel详解(二).mp4 08-Java NIO-Channel-ServerSocketChannel.mp4 09-Java NIO-Channel-SocketChannel.mp4 ...

    java NIO技巧及原理

    Java NIO(New Input/Output)是Java标准库提供的一种I/O模型,它与传统的 Blocking I/O(IO)相比,提供了更加高效的数据传输方式。在Java NIO中,"新"主要体现在非阻塞和多路复用这两个特性上,这使得NIO更适合于...

    java nio 包读取超大数据文件

    ### Java NIO 处理超大数据文件的知识点详解 #### 一、Java NIO简介 Java NIO(New IO)是Java平台上的新输入/输出流API,它提供了与传统IO(即Java IO)不同的数据处理方式。NIO在Java 1.4版本引入,并在后续版本...

    Java NIO测试示例

    在实际应用中,Java NIO通常用于高性能的服务器编程,例如在开发聊天服务器、Web服务器或游戏服务器时,可以利用其高效的并发处理能力。然而,NIO的API相对复杂,学习曲线较陡峭,需要花费一定时间去理解和实践。...

    一个java NIO的例子

    Java NIO,全称为Non-Blocking Input/Output(非阻塞输入/输出),是Java标准库提供的一种替代传统I/O模型的新技术。在传统的Java IO模型中,读写操作是阻塞的,即当调用read或write方法时,线程会等待数据准备好或...

    Java Nio selector例程

    java侧起server(NioUdpServer1.java),基于Java Nio的selector 阻塞等候,一个android app(NioUdpClient1文件夹)和一个java程序(UI.java)作为两个client分别向该server发数据,server收到后分别打印收到的消息...

    java NIO实例

    Java NIO,全称为Non-Blocking Input/Output(非阻塞输入/输出),是Java从1.4版本开始引入的一种新的I/O模型,它为Java应用程序提供了更高效的数据传输...学习和理解NIO,对于开发高并发、高性能的Java应用至关重要。

Global site tag (gtag.js) - Google Analytics