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:

Tiến hành chạy file RunServer.bat ta được:

Chạy file RunClient.bat ta được

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