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]  : 恭喜你抽到了屠龍刀
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章