Tải bản đầy đủ (.doc) (46 trang)

BaoCaoThucHanhLapTrinhMang hoangtuannhan 102120239 12t4 11b

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (6.4 MB, 46 trang )

BÀI THỰC HÀNH SỐ 1 HỌC PHẦN LẬP TRÌNH
MẠNG
Câu 1.
a. Đề bài
Xây dựng chương trình hội thoại Client/Server hoạt động theo giao thức TCP/IP
-

Chương trình Server mở cổng và chờ nhận kết nối từ Client.

-

Client gửi một chuỗi ký tự đến Server. Server nhận và xử lý gửi trả về cho
client các công việc:
+ Đổi chuỗi đã gửi thành chuỗi in hoa
+ Đổi chuỗi đã gửi thành chuỗi thường
+ Đếm số từ của chuỗi đã gửi

b. Thuật toán
Vẽ hình
/*+ Chương trình client nhập vào 1 chuỗi từ bàn phím và gửi lên server thông qua
socket (thông qua DataOutputStream dùng hàm writeUTF()), và chờ nhận dữ liệu từ
server trả về thông qua socket (thông qua DataOutputStream dùng hàm readUTF())
+ Chương trình server chờ nhận kết nối từ client, nếu có kết nối tạo 1 luồng để thực
hiện công việc.
+ Đổi chuỗi thành chuỗi in hoa dùng hàm toUpperCase()
+ Đổi chuỗi thành chuỗi in thường dùng hàm toLowerCase()
+ Đếm số từ của chuỗi đã gửi: Giả sử các từ trong chuỗi cách nhau bởi dấu cách
(khoảng trắng), dấu chấm, dấu phẩy. Dùng hàm split(“[ ,.]”) tách chuỗi bởi dấu cách,
dấu phẩy, dấu chấm. Sau đó ta loại bỏ các phần tử rỗng trong mảng vừa tách được. Số
phần tử còn lại của mảng chính là số từ của chuỗi.
+ Sau đó gửi 3 chuỗi này về cho client đó bằng socket (thông qua DataOutputStream


dùng hàm writeUTF())
*/

c. Mã nguồn chương trình
-

Client1.java

public class Client1 {
public static void main(String[] args) {
try {
Socket client = new Socket("localhost", 2500);


//gửi
Scanner keyboard = new Scanner(System.in);
System.out.println("Nhập chuỗi:");
String sendData = keyboard.nextLine();
DataOutputStream dout = new
DataOutputStream(client.getOutputStream());
dout.writeUTF(sendData);
//nhận
DataInputStream din = new
DataInputStream(client.getInputStream());
System.out.println("Chuỗi sau khi xử lý");
System.out.println("Chuỗi in hoa: "+din.readUTF());
System.out.println("Chuỗi in thường: "+din.readUTF());
System.out.println("Số từ trong chuỗi: "+din.readUTF());
//đóng
din.close();

dout.close();
client.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}

-

Server1.java

public class Server1 {
public static void main(String[] args) {
try {
ServerSocket server = new ServerSocket(2500);
while (true) {
new ThreadSocket(server.accept()).start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
class ThreadSocket extends Thread {
Socket client = null;
public ThreadSocket(Socket client) {
this.client = client;
}
public void run() {

try {
DataInputStream din = new
DataInputStream(client.getInputStream());
DataOutputStream dout = new
DataOutputStream(client.getOutputStream());
String receiveData = din.readUTF();
System.out.println("Chuỗi nhận từ client:" +
receiveData);
dout.writeUTF(receiveData.toUpperCase());
dout.writeUTF(receiveData.toLowerCase());
dout.writeUTF(String.valueOf(demTu(receiveData)));
din.close();
dout.close();
client.close();
} catch (IOException e) {
e.printStackTrace();
}


}
public static int demTu(String chuoi){
String[] tu = chuoi.split("[ ,.]");
int count = tu.length;
for (int i = 0; i < tu.length; i++) {
if(tu[i].equals("")||tu[i].equals(",")||
tu[i].equals(".")){
count--;
}
}
return count;

}
}

d. Kết quả demo

Câu 2.
a. Đề tài
Xây dựng chương trình hội thoại Client/Server hoạt động theo giao thức TCP/IP
-

Chương trình Client cho phép nhập vào từ bàn phím một chuỗi biễu diễn
một phép tính gồm các toán tử +, -, (, ).

Ví dụ:
5+13-(12-4*6) –((3+4)-5)
Chương trình Server thực hiện tính toán và trả kết quả về cho Client

b. Thuật toán
+ Chương trình client gửi và nhận chuỗi thông qua socket : gửi thông qua
DataOutputStream dùng hàm writeUTF()) và nhận thông qua
DataOutputStream dùng hàm readUTF().
+ Chương trình server chờ nhận kết nối từ client, nếu có kết nối tạo 1 luồng để
thực hiện công việc nhận chuỗi thông qua DataOutputStream dùng hàm
readUTF().
+ Tính toán với chuỗi đã nhận theo thuật toán Balan: Duyệt từng kí tự đầu đến
cuối chuỗi:
- Nếu kí tự này là toán tử “+”, “-“, “*”, “/” thì đưa vào ngăn xếp St, trước khi
đưa vào thì thực hiện vòng lặp lấy 2 toán hạng trên đỉnh ngăn xếp Sh và 1 toán
tử trên đỉnh ngăn xếp St thực hiện phép toán với nhau, đẩy kết quả vào ngăn



xếp Sh, khi ngăn xếp St không rỗng và độ ưu tiên của toán tử này nhỏ hơn hoặc
bằng với độ ưu tiên của toán tử ở đỉnh ngăn xếp St
- Nếu kí tự là toán tử “(” thì đưa vào ngăn xếp St, nếu là toán tử “)” thì thực
hiện vòng lặp lấy 2 toán hạng trên đỉnh ngăn xếp Sh và 1 toán tử trên đỉnh ngăn
xếp St thực hiện phép toán với nhay, đẩy kết quả vào ngăn xếp Sh, cho đến khi
nào gặp toán tử “)” trên đỉnh ngăn xếp St, lấy dấu “)” ra khỏi St.
- Còn lại nếu gặp kí tự số thì nối chuỗi cho đến khi gặp kí tự khác số hoặc cuối
chuỗi thì dừng, đẩy chuỗi số ghép được vào ngăn xếp Sh.
- Thực hiện vòng lặp lấy 2 toán hạng trên đỉnh ngăn xếp Sh và 1 toán tử trên
đỉnh ngăn xếp St thực hiện phép toán với nhay, đẩy kết quả vào ngăn xếp Sh,
cho đến khi nào ngăn xếp St rỗng.
- Kết quả tính toán cuối cùng của chuỗi là kí tự còn lại duy nhất trên đỉnh ngăn
xếp Sh.
- Gửi kết quả tính được thông qua DataOutputStream dùng hàm writeUTF()

c. Mã nguồn chương trình
-

Client2.java

public class Client2 {
public static void main(String[] args) {
try {
Socket client = new Socket("localhost", 1994);
//gửi
Scanner keyboard = new Scanner(System.in);
System.out.println("Nhập chuỗi phép tính:");
String sendData = keyboard.nextLine();
DataOutputStream dout = new

DataOutputStream(client.getOutputStream());
dout.writeUTF(sendData);
//nhận
DataInputStream din = new
DataInputStream(client.getInputStream());
String receiveData = din.readUTF();
System.out.println("Kết quả sau khi xử lý:"+receiveData);
din.close();
dout.close();
client.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}

-

Server2.java

public class Server2 {
public static void main(String[] args) {
try {
ServerSocket server = new ServerSocket(1994);
System.out.println(


"Tạo server với địa chỉ: " +
server.getInetAddress() + " cổng cục bộ:" + server.getLocalPort());
while (true) {

new ThreadSocket12(server.accept()).start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
class ThreadSocket12 extends Thread {
Socket client = null;
public ThreadSocket12(Socket client) {
this.client = client;
}
public void run() {
try {
DataInputStream din = new
DataInputStream(client.getInputStream());
DataOutputStream dout = new
DataOutputStream(client.getOutputStream());
String receiveData = din.readUTF();
System.out.println("Chuỗi nhận từ client:"+receiveData);
dout.writeUTF(String.valueOf((tinhTrungTo(receiveData))));
din.close();
dout.close();
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public static int uuTien(String c) {
if (c.equals("+") || c.equals("-"))

return 1;
if (c.equals("*") || c.equals("/"))
return 2;
return 0;
}
public static int isToanTu(String c) {
if (uuTien(c) == 0) {
if (!c.equals("(") && !c.equals(")"))
return 0;
else
return 1;
}
return 2;
}
public static String tinhToan(String a, String b, String i) {
double x = Double.parseDouble(a);
double y = Double.parseDouble(b);
switch (i) {
case "+":
return x + y + "";
case "-":
return x - y + "";
case "*":
return x * y + "";
case "/":
return x / y + "";


default:
return "0";

}

}
public static String tinhTrungTo(String chuoi) {
Stack<String> St = new Stack<String>();
Stack<String> Sh = new Stack<String>();
String number = "";
for (int i = 0; i < chuoi.length(); i++) {
String kitu = String.valueOf(chuoi.charAt(i));
if (isToanTu(kitu) == 0 && i!=chuoi.length()-1) {
number += kitu;
} else {
if(isToanTu(kitu) == 0 && i==chuoi.length()-1){
number+=kitu;
}
if (number.length() > 0) {// là số đưa vào Sh
Sh.push(number);
number = "";
}
if (isToanTu(kitu) == 1) {// là dấu ngoặc
if (kitu.equals("(")) St.push("(");
else if (kitu.equals(")")) {
while (!St.peek().equals("(")) {
String a = Sh.pop();
String b = Sh.pop();
Sh.push(tinhToan(b, a,St.pop()));
}
St.pop();
}
} else if(isToanTu(kitu)==2){

while (!St.isEmpty()&&uuTien(kitu)<=
uuTien(St.peek())) {
String a = Sh.pop();
String b = Sh.pop();
Sh.push(tinhToan(b, a, St.pop()));
}
St.push(kitu);
}
}
}
while (!St.isEmpty()) {
String a = Sh.pop();
String b = Sh.pop();
Sh.push(tinhToan(b, a, St.pop()));
}
return Sh.pop();
}
}

c. Kết quả demo


Câu 3.
a. Đề bài
Xây dựng chương trình hội thoại chat room Client/Server hoạt động theo giao thức
TCP/IP
-

Chương trình Server mở cổng chờ nhận kết nối từ Client.


-

Chương trình Client kết nối và thực hiện trao đổi với chương trình Server.

b. Thuật toán
-

Chương trình Client nhập vào IP của máy Server và cổng để kết nối đến
Server và tạo nên 1 giao diện chat room, khi đó Client sẽ gửi 1 thông báo lên
server rằng client này đã tham gia phòng chat và khi client nhập vào tin nhắn
và nhấn nút Send thì nội dung tin nhắn này sẽ được gửi lên server thông qua
socket (DataOutputStream dùng hàm writeUTF()). Khi tạo giao diện xong thì
sẽ tạo ra 1 luồng nhận tin nhắn từ server thông qua socket (DataInputStream
dùng hàm readUTF()) và nối tin nhắn nhận được vào bảng hiển thị.

-

Chương trình server nhập vào cổng để tạo ServerSocket. Và luôn ở trong tình
trạng chờ nhận kết nối của client, nếu có client kết nối tới thì kiểm tra xem
client này đã kết nối trước đó chưa, nếu chưa thì tạo 1 luồng để làm việc với
client này. Client này sẽ được đưa vào 1 Hashtable (chứa tất cả client đã kết
nối với server), luồng này sẽ nhận tất cả tin nhắn đến từ client đó thông qua
socket (DataInputStream dùng hàm readUTF()) và gửi tin nhắn đó đến tất cả
client đã kết nối với server. Duyệt tất cả phần tử trong Hastable để gửi. Khi
gửi tin nhắn đến tất cả client ta dùng synchronized để tránh xung đột khi gửi.
Gửi tin nhắn thông qua socket (DataOutputStream dùng hàm writeUTF())

c. Mã nguồn chương trình
-


Login.java
(Để đăng ký tên, nhập địa chỉ IP và cổng server cần kết nối)

public class Login extends JFrame implements ActionListener{
JTextField tfUser;
public Login(String title) {
super(title);
JPanel p1 = new JPanel();
JPanel p2 = new JPanel();
JPanel p3 = new JPanel();
JPanel p4 = new JPanel();
JPanel p5 = new JPanel();
JLabel lbTitle = new JLabel("Chat Room TCP");
lbTitle.setFont(new Font(lbTitle.getName(), Font.PLAIN, 40));
JLabel lbUser = new JLabel("User");
tfUser = new JTextField(30);
JButton btnLogin = new JButton("Login");
JButton btnReset = new JButton("Reset");
JButton btnExit = new JButton("Exit");


btnLogin.addActionListener(this);
btnReset.addActionListener(this);
btnExit.addActionListener(this);
JLabel lbAuthor = new JLabel("Author: Ngô Viết Thành");
p1.add(lbTitle);
p2.add(lbUser);
p2.add(tfUser);
p4.add(btnLogin);
p4.add(btnReset);

p4.add(btnExit);
p5.add(lbAuthor);
add(p1);
add(p2);
add(p3);
add(p4);
add(p5);
setSize(400, 300);
setLocation(200, 50);
setLayout(new GridLayout(5, 1));
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
@Override
public void actionPerformed(ActionEvent e) {
String btn=e.getActionCommand();
if(btn.equals("Login")){
String user = tfUser.getText();
String ip = JOptionPane.showInputDialog("Nhập vào IP máy
chủ", "localhost");
int port =
Integer.parseInt(JOptionPane.showInputDialog("Nhập vào port máy chủ",
"1221"));
new Room(user,ip,port);
dispose();
}
if(btn.equals("Reset")){
tfUser.setText("");
}
if(btn.equals("Exit")){

System.exit(0);
}
}
public static void main(String[] args) {
new Login("Đăng nhập");
}
}

-

Room.java
(Chương trình client để nhận và gửi tin nhắn)

public class Room extends JFrame implements Runnable{
JTextArea taMessage, taAllMessage;
JList<String> listUser=new JList<String>();
String user, ip;
int port;
private Socket socket;
private DataInputStream din;
private DataOutputStream dout;
public Room(String user, String ip, int port){


super("Chat Room TCP:");
this.user = user;
this.ip = ip;
this.port = port;
createUI();
try {

System.out.println(ip+" "+port);
socket = new Socket(ip, port);
din = new DataInputStream(socket.getInputStream());
dout = new DataOutputStream(socket.getOutputStream());
dout.writeUTF(this.user);
new Thread(this).start();
} catch (Exception e) {
e.printStackTrace();
}
}
public void createUI(){
setDefaultCloseOperation(EXIT_ON_CLOSE);
JPanel p0= new JPanel();
JLabel lbTitle = new JLabel("----"+ user+" : "+ip+" ----");
p0.add(lbTitle);
add(p0,"North");
JPanel p1= new JPanel();
p1.setLayout(new BorderLayout());
taAllMessage = new JTextArea();
taAllMessage.setWrapStyleWord(true);
taAllMessage.setLineWrap(true);
taAllMessage.setEditable(false);
JScrollPane spAllMessage = new JScrollPane(taAllMessage);
spAllMessage.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR
_ALWAYS);
p1.add(spAllMessage);
add(p1);
JPanel p2= new JPanel();
p2.setLayout(new BorderLayout());
taMessage = new JTextArea(3,35);

taMessage.setWrapStyleWord(true);
taMessage.setLineWrap(true);
JScrollPane spMessage = new JScrollPane(taMessage);
p2.add(spMessage);
JButton btnSend = new JButton("Send");
btnSend.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
try {
dout.writeUTF(taMessage.getText());
taMessage.setText("");
} catch (IOException e1) {
e1.printStackTrace();
}
}
});
p2.add(btnSend, "East");
add(p2, "South");
setSize(350, 300);
setLocation(400, 100);
setVisible(true);
}
@Override


public void run() {
try {
while (true) {
String message = din.readUTF();
taAllMessage.append(message + "\n");

}
} catch (Exception e) {
e.printStackTrace();
}
}
}

-

Server.java (Nhận kết nối từ Client)

public class Server{
ServerSocket server;
public Server(int port) {
listen(port);
}
public void listen(int port){
try {
System.out.println(port);
server = new ServerSocket(port);
while(true){
Socket client = server.accept();
if(client.isConnected()){
ConnectionThread connectionThread = new
ConnectionThread(server, client);
connectionThread.start();
}
}
} catch (Exception e) {
e.printStackTrace();

}
}
public static void main(String[] args) {
int port = Integer.parseInt(JOptionPane.showInputDialog("Nhập
port máy chủ: ","1221"));
new Server(port);
}
}

ConnectionThread.java
(Luồng làm việc trên server)
public class ConnectionThread extends Thread{
private Socket client;
ServerSocket server;
private DataInputStream din;
private DataOutputStream dout;
private static Hashtable<Socket,ConnectionThread> allConnections =
new Hashtable<Socket,ConnectionThread>();
public ConnectionThread(ServerSocket server, Socket client) {
this.connectionNumber = allConnections.size();
allConnections.put(client,this);
this.server= server;
this.client=client;
}
public void run(){
try {


din = new DataInputStream(client.getInputStream());
dout = new DataOutputStream(client.getOutputStream());

String user=din.readUTF();
messageAllSockets(user+" đã tham gia vào phòng chat.");
String receiveData;
while(( receiveData = din.readUTF())!=null){
messageAllSockets(user+": "+receiveData);
}
} catch (Exception e) {
e.printStackTrace();
}

}
public void messageAllSockets(String message){
synchronized (allConnections) {
for (Enumeration<?> e = allConnections.elements();
e.hasMoreElements();) {
ConnectionThread ct = (ConnectionThread)
e.nextElement();
try {
ct.dout.writeUTF(message);
} catch (Exception e2) {
e2.printStackTrace();
}
}
}
}
}

d. Kết quả demo
Khởi động server


Đăng ký tên để chat

Nhập vào IP và cổng của server


Tiến hành chat (ví dụ phòng chat có 4 người)


BÀI THỰC HÀNH SỐ 2 HỌC PHẦN LẬP TRÌNH
MẠNG
Câu 1.
a. Đề bài
Xây dựng chương trình hội thoại Client/Server hoạt động theo giao thức UDP
-

Chương trình Server mở cổng và chờ nhận kết nối từ Client.

-

Client gửi một chuỗi ký tự đến Server. Server nhận và xử lý gửi trả về cho
client các công việc:
+ Đổi chuỗi đã gửi thành chuỗi in hoa
+ Đổi chuỗi đã gửi thành chuỗi thường
+ Đếm số từ của chuỗi đã gửi.

b. Thuật toán
+ Chương trình client nhập vào 1 chuỗi từ bàn phím, đóng gói dữ liệu vào
DatagramPacket dưới dạng byte và gửi lên server thông qua DatagramSocket (dùng
hàm send()), và chờ nhận gói dữ liệu DatagramPacket từ server trả về thông qua
DatagramSocket (dùng hàm receive())

+ Chương trình server chờ và nhận gói dữ liệu DatagramPacket từ client thông qua
DatagramSocket (dùng hàm receive()), từ DatagramPacket ta lấy port và InetAddress.
+ Đổi chuỗi thành chuỗi in hoa dùng hàm toUpperCase()
+ Đổi chuỗi thành chuỗi in thường dùng hàm toLowerCase()
+ Đếm số từ của chuỗi đã gửi: Giả sử các từ trong chuỗi cách nhau bởi dấu cách
(khoảng trắng), dấu chấm, dấu phẩy. Dùng hàm split(“[ ,.]”) tách chuỗi bởi dấu cách,
dấu phẩy, dấu chấm. Sau đó ta loại bỏ các phần tử rỗng trong mảng vừa tách được. Số
phần tử còn lại của mảng chính là số từ của chuỗi.
+ Sau đó nối 3 chuỗi kết quả này thành 1 và cùng với port và InetAddress đã lấy để
tạo DatagramPacket gửi về cho client thông qua DatagramSocket (dùng hàm send()).

c. Mã nguồn chương trình
-

ClientUDP.java

public class ClientUDP {
public static void main(String[] args) {
DatagramPacket sendPackage;
DatagramPacket receivePackage;
byte[] sendData = new byte[1024];


byte[] receiveData = new byte[1024];
try {
DatagramSocket client = new DatagramSocket();
System.out.println("Client ready");
//gui
Scanner keyboard = new Scanner(System.in);
String message = keyboard.nextLine();

sendData = message.getBytes();
InetAddress IPAddress =
InetAddress.getByName("localhost");
sendPackage = new DatagramPacket(sendData,
sendData.length, IPAddress, 9876);
client.send(sendPackage);
//nhan
System.out.println("Ket qua nhan tu Server:");
while(true){
try{
receivePackage = new
DatagramPacket(receiveData, receiveData.length);
client.receive(receivePackage);
receiveData = receivePackage.getData();
String result = new
String(receiveData).trim();
System.out.println(result);
}
catch(Exception e){
break;
}
}
client.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}

-


ServerUDP.java

public class ServerUDP {
public static void main(String[] args) {
DatagramPacket sendPackage;
DatagramPacket receivePackage;
byte[] sendData = new byte[1024];
byte[] receiveData = new byte[1024];
try {
DatagramSocket server = new DatagramSocket(9876);
// nhan
System.out.println("Server ready");
receivePackage = new DatagramPacket(receiveData,
receiveData.length);
server.receive(receivePackage);
receiveData = receivePackage.getData();
String result = new String(receiveData).trim();
System.out.println(result);
InetAddress address = receivePackage.getAddress();
int port = receivePackage.getPort();
sendData = (result.toUpperCase() +"\n" +
result.toLowerCase() +"\n"+demTu(result)).getBytes();
sendPackage = new DatagramPacket(sendData,
sendData.length, address, port);
server.send(sendPackage);


server.close();
} catch (Exception e) {

e.printStackTrace();
}
}
public static int demTu(String chuoi){
String[] tu = chuoi.split("[ ,.]");
int count = tu.length;
for (int i = 0; i < tu.length; i++) {
if(tu[i].equals("")||tu[i].equals(",")||
tu[i].equals(".")){
count--;
}
}
return count;
}
}

d. Kết quả demo

Câu 2.
a. Đề bài
Xây dựng chương trình hội thoại Client/Server hoạt động theo giao thức UDP
-

Chương trình Client cho phép nhập vào từ bàn phím một chuỗi biễu diễn một
phép tính gồm các toán tử +, -, (, ).
Ví dụ:
5+13-(12-4*6) –((3+4)-5)
Chương trình Server thực hiện tính toán và trả kết quả về cho Client

b. Thuật toán

+ Chương trình client nhập vào 1 chuỗi từ bàn phím, đóng gói dữ liệu vào
DatagramPacket dưới dạng byte và gửi lên server thông qua DatagramSocket (dùng
hàm send()), và chờ nhận gói dữ liệu DatagramPacket từ server trả về thông qua
DatagramSocket (dùng hàm receive())
+ Chương trình server chờ và nhận gói dữ liệu DatagramPacket từ client thông qua
DatagramSocket (dùng hàm receive()), từ DatagramPacket ta lấy port và InetAddress


+ Tính toán với chuỗi đã nhận theo thuật toán Balan: Duyệt từng kí tự đầu đến cuối
chuỗi:
- Nếu kí tự này là toán tử “+”, “-“, “*”, “/” thì đưa vào ngăn xếp St, trước khi đưa vào
thì thực hiện vòng lặp lấy 2 toán hạng trên đỉnh ngăn xếp Sh và 1 toán tử trên đỉnh
ngăn xếp St thực hiện phép toán với nhau, đẩy kết quả vào ngăn xếp Sh, khi ngăn xếp
St không rỗng và độ ưu tiên của toán tử này nhỏ hơn hoặc bằng với độ ưu tiên của
toán tử ở đỉnh ngăn xếp St
- Nếu kí tự là toán tử “(” thì đưa vào ngăn xếp St, nếu là toán tử “)” thì thực hiện vòng
lặp lấy 2 toán hạng trên đỉnh ngăn xếp Sh và 1 toán tử trên đỉnh ngăn xếp St thực hiện
phép toán với nhay, đẩy kết quả vào ngăn xếp Sh, cho đến khi nào gặp toán tử “)” trên
đỉnh ngăn xếp St, lấy dấu “)” ra khỏi St.
- Còn lại nếu gặp kí tự số thì nối chuỗi cho đến khi gặp kí tự khác số hoặc cuối chuỗi
thì dừng, đẩy chuỗi số ghép được vào ngăn xếp Sh.
- Thực hiện vòng lặp lấy 2 toán hạng trên đỉnh ngăn xếp Sh và 1 toán tử trên đỉnh
ngăn xếp St thực hiện phép toán với nhay, đẩy kết quả vào ngăn xếp Sh, cho đến khi
nào ngăn xếp St rỗng.
- Kết quả tính toán cuối cùng của chuỗi là kí tự còn lại duy nhất trên đỉnh ngăn xếp
Sh.
- Sau đó đóng gói chuỗi kết quả này và cùng với port và InetAddress đã lấy để tạo
DatagramPacket gửi về cho client thông qua DatagramSocket (dùng hàm send()).

c. Mã nguồn chương trình

-

ClientUDP.java

public class ClientUDP {
private static DatagramSocket client;
private static Scanner keyboard;
public static void main(String[] args) {
DatagramPacket sendPacket;
DatagramPacket receivePacket;
byte[] sendData = new byte[1024];
byte[] receiveData = new byte[1024];
try {
client = new DatagramSocket();
System.out.println("Client ready");
keyboard = new Scanner(System.in);
System.out.println("Nhap vao chuoi can tinh:");
String message = keyboard.nextLine();
InetAddress IPAddress =
InetAddress.getByName("localhost");
sendData = message.getBytes();
sendPacket = new DatagramPacket(sendData,
sendData.length, IPAddress, 9876);
client.send(sendPacket);
//nhan
receivePacket = new DatagramPacket(receiveData,
receiveData.length);


while(true){

try {
client.receive(receivePacket);
receiveData = receivePacket.getData();
message = new String(receiveData).trim();
System.out.println("Tu server: "+message);
} catch (IOException e) {
e.printStackTrace();
break;
}
}

}

} catch (Exception e) {
e.printStackTrace();
}

}

-

ServerUDP.java

public class ServerUDP {
public static void main(String[] args) {
DatagramPacket sendPackage;
DatagramPacket receivePackage;
byte[] sendData = new byte[1024];
byte[] receiveData = new byte[1024];
try {


DatagramSocket server = new DatagramSocket(9876);
System.out.println("Server ready");
receivePackage = new DatagramPacket(receiveData,
receiveData.length);
server.receive(receivePackage);
receiveData = receivePackage.getData();
String result = new String(receiveData).trim();
System.out.println(result);
InetAddress address = receivePackage.getAddress();
int port = receivePackage.getPort();
sendData =
String.valueOf(tinhTrungTo(result)).getBytes();
sendPackage = new DatagramPacket(sendData,
sendData.length, address, port);
server.send(sendPackage);
server.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public static int uuTien(String c){
if(c.equals("+")||c.equals("-")) return 1;
if(c.equals("*")||c.equals("/")) return 2;
return 0;
}
public static int isToanTu(String c){
if(uuTien(c)==0){
if(!c.equals("(")&&!c.equals(")")) return 0;
else return 1;

}
return 2;
}
public static String tinhToan(String a, String b, String i){


double x = Double.parseDouble(a);
double y = Double.parseDouble(b);
switch (i) {
case "+":
return x+y+"";
case "-":
return x-y+"";
case "*":
return x*y+"";
case "/":
return x/y+"";
default:
return "0";
}
}
public static String tinhTrungTo(String chuoi) {
Stack<String> St = new Stack<String>();
Stack<String> Sh = new Stack<String>();
String number = "";
for (int i = 0; i < chuoi.length(); i++) {
String kitu = String.valueOf(chuoi.charAt(i));
if (isToanTu(kitu) == 0 && i!=chuoi.length()-1) {
number += kitu;
} else {

if(isToanTu(kitu) == 0 && i==chuoi.length()-1){
number+=kitu;
}
if (number.length() > 0) {// là số đưa vào Sh
Sh.push(number);
number = "";
}
if (isToanTu(kitu) == 1) {// là dấu ngoặc
if (kitu.equals("("))
St.push("(");
else if (kitu.equals(")")) {
while (!St.peek().equals("(")) {
String a = Sh.pop();
String b = Sh.pop();
Sh.push(tinhToan(a, b,
St.pop()));
}
St.pop();
}
} else if(isToanTu(kitu)==2){
while (!St.isEmpty() && uuTien(kitu) <=
uuTien(St.peek())) {
String a = Sh.pop();
String b = Sh.pop();
Sh.push(tinhToan(a, b, St.pop()));
}
St.push(kitu);
}
}
}

while (!St.isEmpty()) {
String a = Sh.pop();
String b = Sh.pop();
Sh.push(tinhToan(b, a, St.pop()));
}
return Sh.pop();
}


}

d. Kết quả demo

Câu 3.
a. Đề bài
Xây dựng chương trình hội thoại chat room Client/Server hoạt động theo giao thức
UDP
-

Chương trình Server mở cổng chờ nhận kết nối từ Client.
Chương trình Client kết nối và thực hiện trao đổi với chương trình Server.

b. Thuật toán
- Chương trình Client nhập vào IP của máy Server và cổng để kết nối đến Server và
tạo nên 1 giao diện chat room, khi đó Client sẽ gửi 1 thông báo lên server rằng client
này đã tham gia phòng chat, đóng gói dữ liệu vào DatagramPacket dưới dạng byte và
gửi lên server thông qua DatagramSocket (dùng hàm send()). Khi client nhập vào tin
nhắn và nhấn nút Send thì nội dung tin nhắn này sẽ được gửi lên server qua
DatagramPacket dưới dạng byte và gửi lên server thông qua DatagramSocket (dùng
hàm send()). Khi tạo giao diện xong thì sẽ tạo ra 1 luồng nhận gói tin nhắn thông qua

DatagramPacket từ server trả về thông qua DatagramSocket (dùng hàm receive()) và
nối tin nhắn nhận được vào bảng hiển thị.
- Chương trình server nhập vào cổng để tạo ServerSocket. Và luôn ở trong tình trạng
chờ nhận gói dữ liệu DatagramPacket từ client gửi lên thông qua DatagramSocket
(dùng hàm receive()), nếu có gói dữ liệu tới thì tạo 1 luồng để làm việc với gói
DatagramPacket này. Từ gói dữ liệu DatagramPacket ta lấy port và Adress, kiểm tra
xem trong Hastable (chứa những client đã kết nối tới server, lưu port làm key và
address làm value) đã chứa port này chưa, nếu chưa thì bổ sung client này vào. Duyệt
tất cả phần tử trong Hastable để lấy port và address cùng với nội dung tin nhắn đóng
gói vào DatagramPacket Gửi tin thông qua DatagramSocket (dùng hàm send()). Khi
gửi tin nhắn đến tất cả client ta dùng synchronized để tránh xung đột khi gửi.


c. Mã nguồn chương trình
Login.java
(Để đăng ký tên, nhập địa chỉ IP và cổng server cần kết nối)
public class Login extends JFrame implements ActionListener{
JTextField tfUser;
public Login(String title) {
super(title);
JPanel p1 = new JPanel();
JPanel p2 = new JPanel();
JPanel p3 = new JPanel();
JPanel p4 = new JPanel();
JLabel lbTitle = new JLabel("Chat Room UDP");
lbTitle.setFont(new Font(lbTitle.getName(), Font.PLAIN, 40));
JLabel lbUser = new JLabel("User");
tfUser = new JTextField(20);
JButton btnLogin = new JButton("Login");
JButton btnReset = new JButton("Reset");

JButton btnExit = new JButton("Exit");
btnLogin.addActionListener(this);
btnReset.addActionListener(this);
btnExit.addActionListener(this);
p1.add(lbTitle);
p2.add(lbUser);
p2.add(tfUser);
p4.add(btnLogin);
p4.add(btnReset);
p4.add(btnExit);
add(p1);
add(p2);
add(p3);
add(p4);
setSize(350, 300);
setLocation(200, 50);
setLayout(new GridLayout(5, 1));
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
@Override
public void actionPerformed(ActionEvent e) {
String btn=e.getActionCommand();
if(btn.equals("Login")){
String user = tfUser.getText();
String ip = JOptionPane.showInputDialog("Nhập vào IP máy
chủ", "localhost");
int port =
Integer.parseInt(JOptionPane.showInputDialog("Nhập vào port máy chủ",
"1221"));

new Room(user,ip,port);
dispose();
}
if(btn.equals("Reset")){
tfUser.setText("");
}
if(btn.equals("Exit")){
System.exit(0);
}
}
public static void main(String[] args) {


}

new Login("Đăng nhập");

}

Room.java
(Nhận và gửi tin nhắn)
public class Room extends JFrame implements Runnable{
JTextArea taMessage, taAllMessage;
JList<String> listUser=new JList<String>();
String user;
int port;
private DatagramSocket socket;
private byte[] sendData;
private byte[] receiveData;
private DatagramPacket sendPacket;

private DatagramPacket receivePacket;
private InetAddress IPAddress;
public Room(String user, String ip, int port){
super("Chat Room UDP:");
try {
this.user = user;
this.IPAddress = InetAddress.getByName(ip);
this.port = port;
socket = new DatagramSocket();
createUI();
sendData = new byte[1024];
sendData = (this.user+" đã tham gia phòng
chat").getBytes();
sendPacket = new DatagramPacket(sendData,
sendData.length, IPAddress, this.port);
socket.send(sendPacket);
new Thread(this).start();

}

} catch (Exception e) {
e.printStackTrace();
}

public void createUI(){
setDefaultCloseOperation(EXIT_ON_CLOSE);
JPanel p0= new JPanel();
JLabel lbTitle = new JLabel("----"+ user+" : "+IPAddress+" ---");
p0.add(lbTitle);
add(p0,"North");

JPanel p1= new JPanel();
p1.setLayout(new BorderLayout());
taAllMessage = new JTextArea();
taAllMessage.setWrapStyleWord(true);
taAllMessage.setLineWrap(true);
taAllMessage.setEditable(false);
JScrollPane spAllMessage = new JScrollPane(taAllMessage);
spAllMessage.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWA
YS);
p1.add(spAllMessage);
add(p1);
JPanel p2= new JPanel();
p2.setLayout(new BorderLayout());
taMessage = new JTextArea(3,35);


taMessage.setWrapStyleWord(true);
taMessage.setLineWrap(true);
JScrollPane spMessage = new JScrollPane(taMessage);
p2.add(spMessage);
JButton btnSend = new JButton("Send");
btnSend.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
try {
sendData = new byte[1024];
sendData = (user+":"+
taMessage.getText()).getBytes();
taMessage.setText("");
sendPacket = new DatagramPacket(sendData,

sendData.length, IPAddress, port);
socket.send(sendPacket);
} catch (Exception e1) {
e1.printStackTrace();
}
}
});
p2.add(btnSend, "East");
add(p2, "South");
setSize(350, 300);
setLocation(400, 100);
setVisible(true);
}
@Override
public void run() {
try {
while (true) {
receiveData = new byte[1024];
receivePacket = new DatagramPacket(receiveData,
receiveData.length);
socket.receive(receivePacket);
receiveData = receivePacket.getData();
String message = new String(receiveData).trim();
taAllMessage.append(message + "\n");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}


Server.java
(Nhận tin nhắn và tạo luồng xử lí, gửi)
public class Server{
DatagramSocket server;
DatagramPacket receivePacket;
byte[] receiveData;
public Server(int port) {
listen(port);
}
public void listen(int port){
try {
System.out.println(port);
server = new DatagramSocket(port);


while(true){
receiveData = new byte[1024];
receivePacket = new DatagramPacket(receiveData,
receiveData.length);
server.receive(receivePacket);
ConnectionThread connectionThread = new
ConnectionThread(server,receivePacket);
connectionThread.start();
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {

int port = Integer.parseInt(JOptionPane.showInputDialog("Nhập
port máy chủ: ","1221"));
new Server(port);
}
}

ConnectionThred.java
(Luồng xử lí tin nhắn và gửi tin nhắn đến tất cả client)
public class ConnectionThread extends Thread{
DatagramSocket server;
int connectionNumber;
DatagramPacket sendPacket;
DatagramPacket receivePacket;
byte[] sendData;
byte[] receiveData;
private static Hashtable<Integer,InetAddress> allConnections = new
Hashtable<Integer,InetAddress>();
InetAddress address;
int port;
public ConnectionThread(DatagramSocket server,DatagramPacket
receivePacket) {
this.connectionNumber = allConnections.size();
this.server= server;
this.receivePacket = receivePacket;
}
public void run(){
try {
receiveData = new byte[1024];
receiveData = receivePacket.getData();
String message = new String(receiveData).trim();

address = receivePacket.getAddress();
port = receivePacket.getPort();
if(!allConnections.containsKey(port)){
allConnections.put(port,address);
}
messageAllSockets(message);
} catch (Exception e) {
e.printStackTrace();
}
}
public void messageAllSockets(String message) throws IOException{
synchronized (allConnections) {
Enumeration<Integer> allPort;
allPort = allConnections.keys();


while(allPort.hasMoreElements()){
port = (Integer) allPort.nextElement();
address = allConnections.get(port);
sendData = new byte[1024];
sendData = (message).getBytes();
sendPacket = new DatagramPacket(sendData,
sendData.length, address, port);
server.send(sendPacket);
}
}
}
}

d. Kết quả demo


-

-

Nhập port để tạo Server

-

Đăng ký tên.

Nhập địa chỉ IP và port của máy Server


-

Quá trình chat (Phòng chat có 4 người kết nối)


×