Võ Văn Hải's blog

Chỉ có một điều tuyệt đối đó là mọi thứ đều tương đối…

Lập trình Socket – tạo ứng dụng Calculator

Trong bài này là cách dùng Socket với đa tiến trình trong Java. Các bạn cùng tham khảo nhé!

Đầu tiên ta tạo lớp Server bằng cách tạo 1 ServerSocket lắng nghe trên cổng 9999. Ở đây ta cùng đa tiến trình


package vovanhai.wordpress.com.server;

import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;

public class CalculatorServer {
public static void main(String[] args) {
try{
final ServerSocket svr=new ServerSocket(9999);
System.out.println("Server listening on port 9999...");
while(true){
Socket soc=svr.accept();
new Thread(new CalcRunnable(soc)).start();
}
}catch(Exception ex){
ex.printStackTrace();
}
}
}

class CalcRunnable implements Runnable{
Socket client=null;
CalcRunnable(Socket client){
this.client=client;
}
@Override
public void run() {
try {
//1.Nhận yêu cầu từ client
InputStream is=client.getInputStream();
Scanner in=new Scanner(is);
OutputStream os=client.getOutputStream();
PrintWriter out=new PrintWriter(os,true/*auto-flush*/);
while(in.hasNextLine()){
double a=Double.parseDouble(in.nextLine());
double b=Double.parseDouble(in.nextLine());
char op=in.nextLine().charAt(0);
double kq=tinhtoan(a,b,op);
out.println(kq);
}
} catch (Exception e) {
e.printStackTrace();
}

}
private double tinhtoan(double a, double b, char op) {
double ret=0;
switch(op){
case '+':ret=a+b;break;
case '-':ret=a-b;break;
case '*':ret=a*b;break;
case '/':ret=a/b;break;
}
return ret;
}
}

Sau đó ta tạo lớp client để thử. Ở đây ta sử dụng cơ chế đồ họa để client thao tác với Server. Code như sau


package vovanhai.wordpress.com.client;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;

import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTextField;

public class CalcClientGUI extends JFrame implements ActionListener{
private JTextField tfA,tfB,tfRes,tfAdd;
private JButton btnCong,btnTru,btnNhan,btnChia;
public CalcClientGUI() {
setTitle("Mẹt Calculator");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(300,200);setResizable(false);
setLocation(100,200);

Box b=Box.createVerticalBox();
Box b1=Box.createHorizontalBox();
Box b2=Box.createHorizontalBox();
Box b3=Box.createHorizontalBox();
Box b4=Box.createHorizontalBox();
Box b5=Box.createHorizontalBox();
JLabel l1,l2,l4;

b5.add(l4=new JLabel("Server Address:",JLabel.RIGHT));b5.add(tfAdd=new JTextField("localhost"));
b1.add(l1=new JLabel("Số A:",JLabel.RIGHT));b1.add(tfA=new JTextField());
b2.add(l2=new JLabel("Số B:",JLabel.RIGHT));b2.add(tfB=new JTextField());
b4.add(new JLabel("Kết quả:",JLabel.RIGHT));b4.add(tfRes=new JTextField());

b3.add(btnCong=new JButton("+"));btnCong.addActionListener(this);
b3.add(btnTru=new JButton("-"));btnTru.addActionListener(this);
b3.add(btnNhan=new JButton("*"));btnNhan.addActionListener(this);
b3.add(btnChia=new JButton("/"));btnChia.addActionListener(this);
l1.setPreferredSize(l4.getPreferredSize());
l2.setPreferredSize(l4.getPreferredSize());
tfRes.setEditable(false);

b.add(Box.createVerticalStrut(10));
b.add(b5);b.add(Box.createVerticalStrut(10));
b.add(b1);b.add(Box.createVerticalStrut(10));
b.add(b2);b.add(Box.createVerticalStrut(10));
b.add(b3);b.add(Box.createVerticalStrut(10));
b.add(b4);b.add(Box.createVerticalStrut(10));

this.add(b,BorderLayout.NORTH);
}

@Override
public void actionPerformed(ActionEvent e) {
Object o=e.getSource();
try {
double a=Double.parseDouble(tfA.getText());
double b=Double.parseDouble(tfB.getText());
String op="";

if(o.equals(btnCong)){
op="+";
}
else if(o.equals(btnTru)){
op="-";
}
else if(o.equals(btnNhan))
op="*";
else if(o.equals(btnChia))
op="/";

Socket soc=new Socket(tfAdd.getText(),9999);
Scanner in=new Scanner(soc.getInputStream());
PrintWriter out=new PrintWriter(soc.getOutputStream(),true);
out.println(a);
out.println(b);
out.println(op);

String kq=in.nextLine();
tfRes.setText(kq);
} catch (Exception e2) {
JOptionPane.showMessageDialog(null, e2.getMessage());
}
}
public static void main(String[] args) {
new CalcClientGUI().setVisible(true);
}
}

Sau đó ta tiến hành biên dịch 2 file này. Để dễ thao tác ta tạo các file bat. File build.bat dùng để biên dịch như sau: (Dĩ nhiên bạn đã thiết lập biến môi trường PATH nhé)


javac -d . -encoding UTF-8 *.java
pause

Tạo file RunServer.bat với nội dung sau để chạy Server

java vovanhai.wordpress.com.server.CalculatorServer
pause

Tạo file RunClient.bat với nội dung sau để chạy Client

java vovanhai.wordpress.com.client.CalcClientGUI
pause

Bạn tiến hành chạy file build.bat để biên dịch các file java. Sau khi biên dịch, nếu không có lỗi, ta thu được cấu trúc thư mục như sau:
https://vovanhai.files.wordpress.com/2011/10/calcstructure.png

Tiến hành chạy file RunServer.bat ta được:
https://vovanhai.files.wordpress.com/2011/10/calcserverrun.png

Chạy file RunClient.bat ta được
https://vovanhai.files.wordpress.com/2011/10/calcclientrun.png
Bạn có thể triển khai phần Server ở 1 máy chủ nào đó có địa chỉ/tên server xác định sau đó chạy client ở máy con. Bạn nhập chính xác tên server/ip vào sô server address và các giá trị cần tính ở 2 textfield còn lại và thưởng thức.

Chúc thành công

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: