学习一下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实现...
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...
Java NIO,全称为Non-Blocking Input/Output(非阻塞输入/输出),是Java平台中用于替代标准I/O(BIO)模型的一种新机制。NIO在Java 1.4版本引入,提供了更高效的数据处理和通道通信方式,特别适用于高并发、大数据...
jaca视频教程 jaca游戏服务器端开发 Netty NIO AIO Mina视频教程 课程目录: 一、Netty快速入门教程 01、第一课NIO 02、第二课netty服务端 03、第三课netty客户端 04、第四课netty线程模型源码分析(一) 05、...
Java NIO,全称为Non-...总的来说,Java NIO提供了比传统I/O更灵活、更高效的数据传输机制,尤其适用于需要处理大量并发连接的网络应用,如服务器端的开发。通过合理利用NIO的特性,可以构建出高性能、低延迟的系统。
在学习Java NIO时,这份中文开发文档最全版.pdf将涵盖这些核心概念的详细解释、示例代码以及最佳实践,帮助读者掌握如何在实际项目中应用NIO。对于初学者来说,深入理解这些内容,将有助于构建高效、可扩展的Java...
Java NIO(New IO)是一个可以替代标准Java IO API的IO API(从Java 1.4开始),Java NIO提供了与标准IO不同的IO工作方式。 Java NIO: Channels and Buffers(通道和缓冲区) 标准的IO基于字节流和字符流进行操作的,...
Java NIO 深入探讨了 1.4 版的 I/O 新特性,并告诉您如何使用这些特性来极大地提升您所写的 Java 代码的执行效率。这本小册子就程序员所面临的有代表性的 I/O 问题作了详尽阐述,并讲解了 如何才能充分利用新的 I/O ...
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(New Input/Output)是Java标准库提供的一种I/O模型,它与传统的 Blocking I/O(IO)相比,提供了更加高效的数据传输方式。在Java NIO中,"新"主要体现在非阻塞和多路复用这两个特性上,这使得NIO更适合于...
### Java NIO 处理超大数据文件的知识点详解 #### 一、Java NIO简介 Java NIO(New IO)是Java平台上的新输入/输出流API,它提供了与传统IO(即Java IO)不同的数据处理方式。NIO在Java 1.4版本引入,并在后续版本...
在实际应用中,Java NIO通常用于高性能的服务器编程,例如在开发聊天服务器、Web服务器或游戏服务器时,可以利用其高效的并发处理能力。然而,NIO的API相对复杂,学习曲线较陡峭,需要花费一定时间去理解和实践。...
Java NIO,全称为Non-Blocking Input/Output(非阻塞输入/输出),是Java标准库提供的一种替代传统I/O模型的新技术。在传统的Java IO模型中,读写操作是阻塞的,即当调用read或write方法时,线程会等待数据准备好或...
java侧起server(NioUdpServer1.java),基于Java Nio的selector 阻塞等候,一个android app(NioUdpClient1文件夹)和一个java程序(UI.java)作为两个client分别向该server发数据,server收到后分别打印收到的消息...
Java NIO,全称为Non-Blocking Input/Output(非阻塞输入/输出),是Java从1.4版本开始引入的一种新的I/O模型,它为Java应用程序提供了更高效的数据传输...学习和理解NIO,对于开发高并发、高性能的Java应用至关重要。