1. 程式人生 > >基於TCP的計算器(Java)

基於TCP的計算器(Java)

一款基於TCP通訊的計算器,客戶端通過按鈕向伺服器傳送資料,伺服器對資料進行計算處理,將計算結果傳送回客戶端。當中運用多執行緒進行啟用。

伺服器執行緒: package com.netproject2;

import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket;

public class CalculatorServer extends Thread{ public final double PI=3.1415927;//定義圓周率 Socket client;//定義客戶端套接字 DataInputStream datain=null;//定義資料輸入流接收資料 InputStream in=null; DataOutputStream dataout=null;//定義資料輸出流傳輸資料 OutputStream out=null; float num_one; float num_two; float result;//定義計算結果 int symbol;//定義符號 public CalculatorServer(Socket client){ this.client=client; }

public  void run() {
	
	try {
		in=client.getInputStream();//輸入流接收
		datain=new DataInputStream(in);//流轉換為資料
		out=client.getOutputStream();
		dataout=new DataOutputStream(out);
	while(true){
		symbol=datain.readInt();//讀取數字代替的符號
		switch(symbol){//計算
			case 1:
				num_two=datain.readFloat();//讀取第二次輸入的數字
			    result=(float) Math.sin(num_two*PI/180);
			    dataout.writeFloat(result);break;//向客戶端傳輸計算結果
			case 2:
				num_two=datain.readFloat();//讀取第二次輸入的數字
		   	    result=(float) Math.cos(num_two*PI/180);
		        dataout.writeFloat(result);break;//向客戶端傳輸計算結果
			case 3:
				num_two=datain.readFloat();//讀取第二次輸入的數字
		        result=(float) Math.tan(num_two*PI/180);
		        dataout.writeFloat(result);break;//向客戶端傳輸計算結果
			case 4:
				num_two=datain.readFloat();//讀取第二次輸入的數字
		        result=(float) Math.sqrt(num_two*PI/180);
		        dataout.writeFloat(result);break;//向客戶端傳輸計算結果
			case 5:
				num_one=datain.readFloat();//讀取整型資料
			    num_two=datain.readFloat();//讀取第二次輸入的數字
			    result=num_one+num_two;
			    dataout.writeFloat(result);break;//向客戶端傳輸計算結果
			case 6:
				num_one=datain.readFloat();//讀取整型資料
				num_two=datain.readFloat();//讀取第二次輸入的數字
				result=num_one-num_two;
				dataout.writeFloat(result);break;//向客戶端傳輸計算結果
			case 7:
				num_one=datain.readFloat();//讀取整型資料
				num_two=datain.readFloat();//讀取第二次輸入的數字
				result=num_one*num_two;
				dataout.writeFloat(result);break;//向客戶端傳輸計算結果
			case 8:
				num_one=datain.readFloat();//讀取整型資料
				num_two=datain.readFloat();//讀取第二次輸入的數字
				result=num_one/num_two;
				dataout.writeFloat(result);break;//向客戶端傳輸計算結果
			default:break;
		}
			} 
	}catch (IOException e) {
				e.printStackTrace();
			} 
	try {//關閉套接字及各種流
		in.close();
		datain.close();
		out.close();
		dataout.close();
		client.close();
	} catch (IOException e) {
		System.out.println(client.isConnected());
		e.printStackTrace();
			}
	}
}

伺服器主方法: package com.netproject2;

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

public class DemoServer { //客戶端斷開後可以進行重新連線 public static void main(String[] args) { ServerSocket server=null; Socket client=null; try { server=new ServerSocket(8866);//建立伺服器套接字 System.out.println(“伺服器已啟動,正在等待客戶端連線…”); }catch (IOException e) { System.out.println(“伺服器套接字建立錯誤”); } while(true){ try { client=server.accept();//連線客戶端 System.out.println(“客戶端已連線,可以進行通訊…”+client); } catch (IOException e1){ System.out.println(“客戶端連接出錯”); } if(client!=null){//用於同時連線多個客戶端 new CalculatorServer(client).start(); } } } } 客戶端執行緒: package com.netproject2;

import java.awt.BorderLayout; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket;

import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JTextField; import javax.swing.SwingConstants;

public class CalculatorClient extends JFrame implements Runnable,ActionListener{

	Socket client=null;
	DataInputStream datain=null;
	InputStream in=null;
	DataOutputStream dataout=null;
	OutputStream out=null;
	String[][] inputButtonNames={{"sin","cos","tan","√"},{"1","2","3","+"},{"4","5","6","-"},{"7","8","9","*"},{".","0","=","/"}};
	//定義二維陣列承裝按鈕名稱inputButtonNames
	JTextField show=new JTextField();//建立輸入框textField
	JButton[] inButton=new JButton[20];//建立輸入按鈕inButton
	String[] resetButtonNames={"    清        空     ","    清       除      "};//定義清除按鈕名稱resetButtonNames
	JButton[] resetButton=new JButton[2];//建立清除按鈕resetButton
	String tempText="";//用於臨時存放第一次獲取的按鈕數字(字串)
	
	int symbol=0;//用於判斷運算子號
	float num_one;//用於存放輸入運算子號前的數字(已經過轉換)
	float num_two;//用於存放輸入運算子號後的數字(已經過轉換)
	float result;//用於存放運算結果
	int number=0;//用於判斷輸入的次數 	 
	boolean com=false;//用於判斷是否輸入了運算子號及小數點
	
	
	public CalculatorClient(){//計算面板的無參建構函式		
		super("客戶端");//呼叫父類方法
		this.setBounds(300,300,252, 264);//設定窗體大小及出現在螢幕的位置
		
		JPanel ibp=new JPanel();//建立輸入框面板input box panel
		show.setText("0");//設定輸入框初始數字"0"
		show.setColumns(21);//設定輸入框列數
		show.setEditable(false);//設定輸入框為不可編輯狀態
		show.setHorizontalAlignment(SwingConstants.RIGHT);//設定輸入框的方位:北
		ibp.add(show);//將輸入框新增至輸入框面板
		this.add(ibp, BorderLayout.NORTH);//設定輸入框面板的方位:置北
		
		JPanel bp=new JPanel();//設定輸入按鈕面板button panel
		GridLayout gridLayout=new GridLayout(5,4,4,4);//網格式佈局
		bp.setLayout(gridLayout);//輸入按鈕面板使用網格佈局
		for(int i=0;i<5;i++){//利用陣列、迴圈逐個植入輸入按鈕
			for(int j=0;j<inputButtonNames[0].length;j++){
				inButton[i*4+j]=new JButton(inputButtonNames[i][j]);
				bp.add(inButton[i*4+j]);//將輸入按鈕新增至輸入按鈕面板
				inButton[i*4+j].addActionListener(this);//賦予動作監聽
			}
		}
		this.add(bp, BorderLayout.SOUTH);//設定輸入按鈕面板的方位:置南
		
		JPanel cbp=new JPanel();//建立清除按鈕及三角函式按鈕面板clean button panel		
		for(int i=0;i<resetButtonNames.length;i++){////利用陣列、迴圈逐個植入清除按鈕
			resetButton[i]=new JButton(resetButtonNames[i]);
			cbp.add(resetButton[i]);//將清除按鈕新增至清除按鈕
			resetButton[i].addActionListener(this);//賦予動作監聽
		}
		this.add(cbp, BorderLayout.CENTER);//設定清除按鈕面板的方位:置中
		
		this.setVisible(true);//設定窗體為可見
		
		try {
			client=new Socket("localhost",8866);//建立本地套接字
		} catch (IOException e4) {
			e4.printStackTrace();
		}
		try {
			out=client.getOutputStream();
			dataout=new DataOutputStream(out);
			in=client.getInputStream();
			datain=new DataInputStream(in);
		} catch (IOException ee) {
			ee.printStackTrace();
		}			
	}
	
	public void run(){//執行緒執行
		
	}
	@Override
	public void actionPerformed(ActionEvent e) {
		
		if(e.getSource() == inButton[0]) {//sin的動作監聽
			com=true;
			number=0;
			symbol=1;
			show.setText("sin");
			}
		else if(e.getSource() == inButton[1]) {//cos的動作監聽
			com=true;
			number=0;
			symbol=2;
			show.setText("cos");
			}
		else if(e.getSource() == inButton[2]) {//tan的動作監聽
			com=true;
			number=0;
			symbol=3;
			show.setText("tan");
			}
		else if(e.getSource() == inButton[3]) {//開方的動作監聽
			com=true;
			number=0;
			symbol=4;
			show.setText("√");
			}
		else if (e.getSource() == inButton[4]) {//數字1的動作監聽
			if(com==true||number==0){//第一次輸入
			show.setText("1");//輸出第一次輸入的數字
			number=1;
			com=false;
			}
			else{				//非第一次輸入
				tempText=show.getText();//獲取第一次輸入的數字
				show.setText(tempText+"1");//將n次輸入的數字一同輸出
			}	
		}
		else if (e.getSource() == inButton[5]) {//數字2的動作監聽
			if(com||number==0){
				show.setText("2");
				number=1;
				com=false;
				}
				else{
					tempText=show.getText();
					show.setText(tempText+"2");
				}	
			}
		else if (e.getSource() == inButton[6]) {//數字3的動作監聽
			if(com||number==0){
				show.setText("3");
				number=1;
				com=false;
				}
				else{
					tempText=show.getText();
					show.setText(tempText+"3");
				}	
			}
		else if (e.getSource() == inButton[7]) {	//加號的動作監聽		
			com=true;
			number=0;
			symbol=5;
			num_one=Float.parseFloat(show.getText());//將獲取的字串轉換為數字
			show.setText("+");
		}
		else if (e.getSource() == inButton[8]) {//數字4的動作監聽
			if(com||number==0){
				show.setText("4");
				number=1;
				com=false;
				}
				else{
					tempText=show.getText();
					show.setText(tempText+"4");
				}	
			}
		else if (e.getSource() == inButton[9]) {//數字5的動作監聽
			if(com||number==0){
				show.setText("5");
				number=1;
				com=false;
				}
				else{
					tempText=show.getText();
					show.setText(tempText+"5");
				}	
			}
		else if (e.getSource() == inButton[10]) {//數字6的動作監聽
			if(com||number==0){
				show.setText("6");
				number=1;
				com=false;
				}
				else{
					tempText=show.getText();
					show.setText(tempText+"6");
				}	
			}
		else if (e.getSource() == inButton[11]) {//減號的動作監聽
			com=true;
			number=0;
			symbol=6;
			num_one=Float.parseFloat(show.getText());//將獲取的字串轉換為數字
			show.setText("-");
			}
		else if (e.getSource() == inButton[12]) {//數字7的動作監聽
			if(com||number==0){
				show.setText("7");
				number=1;
				com=false;
				}
				else{
					tempText=show.getText();
					show.setText(tempText+"7");
				}	
			}
		else if (e.getSource() == inButton[13]) {//數字8的動作監聽
			if(com||number==0){
				show.setText("8");
				number=1;
				com=false;
				}
				else{
					tempText=show.getText();
					show.setText(tempText+"8");
				}	
			}
		else if (e.getSource() == inButton[14]) {//數字9的動作監聽
			if(com||number==0){
				show.setText("9");
				number=1;
				com=false;
				}
				else{
					tempText=show.getText();
					show.setText(tempText+"9");
				}	
			}
		else if (e.getSource() == inButton[15]) {//乘號的動作監聽
			com=true;
			number=0;
			symbol=7;
			num_one=Float.parseFloat(show.getText());//將獲取的字串轉換為數字
			show.setText("*");
			}
		else if (e.getSource() == inButton[16]) {
			if(com||number==0){//有待完善:使得第一次不能按此按鈕
				show.setText(".");
				number=1;
				com=false;
				}
				else{//判斷已獲取的字串中是否含有小數點“.”
					tempText=show.getText();
					if(tempText.indexOf(".")==-1){
						show.setText(tempText+".");
					}
					else{show.setText(tempText);}
				}	
			}
		else if (e.getSource() == inButton[17]) {//數字0的動作監聽
			if(com||number==0){
				show.setText("0");
				number=1;
				com=false;
				}
				else{
					tempText=show.getText();
					show.setText(tempText+"0");
				}	
			}
		else if (e.getSource() == inButton[18]) {//等號的動作監聽
			num_two=Float.parseFloat(show.getText());//獲取輸入運算子號後的字串並轉換
			
			switch(symbol){
				case 1:try {
					   dataout.writeInt(symbol);
					   dataout.writeFloat(num_two);
					   result=datain.readFloat();
				       number=0;//同上註釋
					   show.setText(""+result);
					} catch (IOException e2) {
					e2.printStackTrace();
					}break;
				case 2:try {
					   dataout.writeInt(symbol);
					   dataout.writeFloat(num_two);
					   result=datain.readFloat();
				       number=0;//同上註釋
					   show.setText(""+result);
					} catch (IOException e2) {
					e2.printStackTrace();
					}break;
				case 3:try {
					   dataout.writeInt(symbol);
					   dataout.writeFloat(num_two);
					   result=datain.readFloat();
				       number=0;//同上註釋
					   show.setText(""+result);
					} catch (IOException e2) {
					e2.printStackTrace();
					}break;
				case 4:try {
					   dataout.writeInt(symbol);
					   dataout.writeFloat(num_two);
					   result=datain.readFloat();
				       number=0;//同上註釋
					   show.setText(""+result);
					} catch (IOException e2) {
					e2.printStackTrace();
					}break;
				case 5:try {
					   dataout.writeInt(symbol);
					   dataout.writeFloat(num_one);
					   dataout.writeFloat(num_two);
					   result=datain.readFloat();
				       number=0;//同上註釋
					   show.setText(""+result);
					} catch (IOException e1) {
					e1.printStackTrace();
					}break;
				case 6:try {
					   dataout.writeInt(symbol);
					   dataout.writeFloat(num_one);
					   dataout.writeFloat(num_two);
					   result=datain.readFloat();
					   number=0;//同上註釋
					   show.setText(result+"");
					} catch (IOException e1) {
					e1.printStackTrace();
					}break;
				case 7:try {
					   dataout.writeInt(symbol);
					   dataout.writeFloat(num_one);
					   dataout.writeFloat(num_two);
					   result=datain.readFloat();
					   number=0;//同上註釋
					   show.setText(result+"");
					} catch (IOException e1) {
					e1.printStackTrace();
					}break;
				case 8:try {
					   dataout.writeInt(symbol);
					   dataout.writeFloat(num_one);
					   dataout.writeFloat(num_two);
					   result=datain.readFloat();
					   number=0;//同上註釋
					   show.setText(result+"");
					} catch (IOException e1) {
					e1.printStackTrace();
					}break;
				default:number=0;break;//同上註釋
			}
		}
		else if(e.getSource() == inButton[19]) {//除號的動作監聽
			com=true;
			number=0;
			symbol=8;
			num_one=Float.parseFloat(show.getText());//將獲取的字串轉換為數字
			show.setText("/");
			}
		else if (e.getSource() == resetButton[0]){//清空按鈕AC
			number=0;//效果和等號"number=0"的解釋一樣
			symbol=0;//重置symbol
			show.setText("0");
		}
		else if (e.getSource() == resetButton[1]){//單個位元組清除按鈕C
			number=0;//效果和等號"number=0"的解釋一樣
			symbol=0;//重置symbol
		 	tempText=show.getText();
			if(tempText.equals("sin")||tempText.equals("cos")||tempText.equals("tan")||(tempText.length()-1)==0){//判斷tempText是否為單位元組
				show.setText("0");
			}
			else {
				show.setText(tempText.substring(0,tempText.length()-1));
				 if(tempText.length()==0)
					 {show.setText("0");}
				 }
		}		
	}	
}

客戶端主方法: package com.netproject2;

public class DemoClient {

public static void main(String[] args) {
	
	CalculatorClient p = new CalculatorClient();
     new Thread(p).start();
}

}