Java BIO 服务器

前言

目前流行的NIO网络框架,有netty.mina.我用过一段时间netty,感觉有点爽。由于框架主程已经写好了,我只需要在上面做开发,所以几乎不用太底层的东西,就可以轻松上手。往往遇到一些真正的问题时,就需要去了解下整个框架了。下面我从最基础BIO的开始了解。

一、BIO 一个服务器与多客户端进行通信时,产生的线程个数是1:1.

 

二、服务端如何处理客服端发来的请求.


三、代码实现

1.连接管道
package com;

/**
 * 抽象连接管道
 * @author xuan.lei
 *
 */
public interface IChannel {
	void write(String msg);
	String read();
}

2.指令类型
package com.domain;

public enum Code {
	 PLYAER_PACKGE(1,"玩家背包"),
	 PLAYER_LOTTERY(3,"玩家抽奖"),
	 ENTER_MISSION(2,"进入副本");
	 private int id;
	 private String desc;
	
	 private Code(int id, String desc) {
		this.id = id;
		this.desc = desc;
	 }

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getDesc() {
		return desc;
	}

	public void setDesc(String desc) {
		this.desc = desc;
	}
	 
 
}
3.Client
package com.domain;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Calendar;

import com.IChannel;

public class Client implements IChannel,Runnable {
	private String name;
	private Socket socket;
	PrintWriter out = null;
	BufferedReader in=null;
	public Client( String name) {
		super();
		this.name = name;
	}
	
	public boolean connect(String host,int port){
		try {
			socket = new Socket(host,port);
			out = new PrintWriter(socket.getOutputStream(),true);
			in  = new BufferedReader(new InputStreamReader(socket.getInputStream()));
			return true;
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			//e.printStackTrace();
		}
		return false;
	}

	public void close(){
		try {
			out.close();
			in.close();
			socket.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public boolean isClosed(){
		return socket.isConnected();
 
	}

	public String getName() {
		return name;
	}



	public void setName(String name) {
		this.name = name;
	}



	public Socket getSocket() {
		return socket;
	}



	public void setSocket(Socket socket) {
		this.socket = socket;
	}



	@Override
	public void write(String msg) {
		out.println("["+Calendar.getInstance().getTime().toLocaleString()+"] " +name+" request#"+msg);
	}
	
	@Override
	public String read() {
		try {
			if(in.ready()){
				String body = in.readLine();
				return "recive data from server : "+body;
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			System.out.println("与服务端失去连接");
		} 
		return "";
	}

	@Override
	public void run() {
		while(true){
			 String readMsgFromServer = read();
			 if(!"".equals(readMsgFromServer)){
					 System.out.println(readMsgFromServer);
			 }else {
				 //System.out.println("服务器无响应.");
			 }
		}
		
	}
	 

}
4.服务器处理类
package com.domain;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Calendar;

import com.IChannel;

public class ServerHandler implements IChannel,Runnable {
	
	private Socket socket;
	private boolean isSocketActive;
	PrintWriter out=null;
	BufferedReader in = null;
	
	public ServerHandler(Socket socket, boolean isSocketActive) {
		super();
		this.socket = socket;
		this.isSocketActive = isSocketActive;
	}

	@Override
	public void run() {
		try {
			out = new PrintWriter(socket.getOutputStream(),true);
			in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
		 
			while(true){
				String readMsgFromClient = read();
				if(!"".equals(readMsgFromClient)){
					 System.out.println(readMsgFromClient);
					 int codeIndex = readMsgFromClient.indexOf("#");
					 int code = Integer.valueOf(readMsgFromClient.substring(codeIndex+1));
					 switch(Code.values()[code]){
					 case  PLAYER_LOTTERY:
						   write("恭喜你抽到了屠龙刀");
						 break;
					 case PLYAER_PACKGE:
						   write("已打开玩家背包");
						 break;
					 case ENTER_MISSION:
						   write("已进入副本.");
						 break;
						default:
							out.println("当前命令没有注册。");
							break;
					 }
				}
			} 
		
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{
			out.close();
			try {
				socket.close();
			} catch (IOException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			try {
				in.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
		}
	}

	@Override
	public void write(String msg) {
			out.println("["+Calendar.getInstance().getTime().toLocaleString()+"] "+" : "+msg);

	}

	@Override
	public String read() {
		try {
			if(in.ready()){
				return in.readLine();
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return "";
	}
	
	 
}
5.服务器
package com;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

import com.domain.ServerHandler;

public class ChatServer {
	public static void main(String args[]) throws IOException{
		ServerSocket server = new ServerSocket(9000);
		System.out.println("###########################################");
		System.out.println("Server Start .");
		System.out.println("###########################################");
		while(true){
			Socket accept = server.accept();
			new Thread(new ServerHandler(accept, true)).start();
		}
		
	}
}
6.玩家
package com;
 
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Random;

import com.domain.Client;

public class Player{
	 
	public static void main(String args[]) throws IOException {
		Client client = new Client("编号 "+new Random(System.currentTimeMillis()).nextInt());
		 BufferedReader in=null;
		 in = new BufferedReader(new InputStreamReader(System.in));
		 if(client.connect("127.0.0.1", 9000)){
			 new Thread(client).start();
			 while(true){
				 String readMsgFromConsole = in.readLine();
				 if(!readMsgFromConsole.equals("")){
					 client.write(readMsgFromConsole);
				 }
			 }
		 }
		 
	}

	 

	 
}

运行:
        Sever
###########################################
Server Start .
###########################################
[2015-9-12 15:29:02] 编号 2049638772 request#1




Client
1
recive data from server : [2015-9-12 15:29:02]  : 恭喜你抽到了屠龙刀
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值