Demo. Phần mềm chat mô hình client-server bằng JAVA

Mình vừa viết tool xong.
Mà chỉ là cơ bản thôi, nên muốn được sự góp ý của mọi người.

Ứng dụng mô hình client-server, giao thức TCP, Thread.

Mô hình Client.

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package NetWork.ChatThread;

import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.JTextField;

/**
 *
 * @author user
 */
public class client{
// frame
JFrame j;
Container c;
JTextArea textdis;
JTextField textgui;
JButton gui;

// Biến của socket
Socket s;
OutputStream os;
InputStream is;
inputstream threadnhap;
outputstream threadxuat;
PrintWriter pw;

public client(){
    GUI(); // Giao dien
    KhoiTaoSocKet();   // Socket kêt nói server
}

private void GUI(){
    // frame
    j = new JFrame("Client");
    j.setBounds(10, 10, 500, 500);
    j.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
    // text
    textdis = new JTextArea();
    textdis.setBounds(10, 10, 480, 300);
    textdis.setEditable(false);
    textgui = new JTextField();
    textgui.setBounds(10, 320, 300, 30);
    entertextgui keygui = new entertextgui();
    textgui.addKeyListener(keygui);
    
    // button
    gui = new JButton("Gui");
    gui.setBounds(320, 320, 80, 30);
    guidi gd = new guidi();
    gui.addActionListener(gd);
            
    
    // container
    c= j.getContentPane();
    c.setLayout(null);
    c.add(textdis);
    c.add(textgui);
    c.add(gui);
    
    // hiện frame
    j.setVisible(true);
}
private void KhoiTaoSocKet(){
    try {
        s = new Socket("127.0.0.1",1234);
        os = s.getOutputStream();
        is = s.getInputStream();
    } catch (IOException ex) {
        System.out.println("Loi phan socket: " +ex.getMessage());
        if("Connection refused".equals(ex.getMessage())){
            System.out.println("Chua bat server!");
            textdis.setText("Không có kết nối với SERVER!");
        }
        try {
            Thread.sleep(2000);
        } catch (InterruptedException ex1) {
            Logger.getLogger(client.class.getName()).log(Level.SEVERE, null, ex1);
        }
        System.exit(0);
    }
    
    threadnhap = new inputstream();
    threadnhap.start(); // chạy thread
}

// Hàm để gủi dữ liệu lên Stream
private void nutgui(){
    
    pw =new PrintWriter(os);
    String gui=textgui.getText();
    System.out.println("Gui: "+gui);
    textdis.setText(textdis.getText()+"Me: "+gui+"\n");
    textgui.setText("");
    pw.println(gui); pw.flush();
}


// class key listenr của textgui dùng gõ phím enter để gủi.
class entertextgui implements KeyListener{
    @Override
    public void keyTyped(KeyEvent e) {
    }

    @Override
    public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_ENTER) {
            nutgui();
        }
    }
    @Override
    public void keyReleased(KeyEvent e) {
    }
}

// Thread để chạy cập nhật liên tục input trên Stream
class inputstream extends Thread{

    @Override
    public void run() {
        Scanner sc = new Scanner(is); // Sacnner lấy input liên tục trên stream
        String nhan ="";
        while(true){
            nhan = sc.nextLine();
            textdis.setText(textdis.getText()+"Server: "+nhan+"\n");
            System.out.println("\n---- Nhan: " + nhan);
        }
    }
    
}

class outputstream extends Thread{
    @Override
    public void run() {
        pw =new PrintWriter(os);
        Scanner sc = new Scanner(System.in);
        String gui="";
        while(true){
            System.out.print("Gui: ");
            gui = sc.nextLine();
            pw.println(gui); pw.flush();
        }
    }
}

class guidi implements ActionListener{

    @Override
    public void actionPerformed(ActionEvent e) {
        pw =new PrintWriter(os);
        String gui=textgui.getText();
        System.out.println("Gui: "+gui);
        textdis.setText(textdis.getText()+"Me: "+gui+"\n");
        textgui.setText("");
        pw.println(gui); pw.flush();
    }
}

public static void main(String[] args) {
    client b = new client();
}
}

Mô hình server:

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package NetWork.ChatThread;

import java.awt.Container;
import java.awt.TextArea;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;

/**
 *
 * @author user
 */
public class server {
// frame
JFrame j;
Container c;
JTextArea textdis;
JTextField textgui;
JButton gui;

//
Socket s;
OutputStream os;
InputStream is;
inputstream threadnhap;

PrintWriter pw;
ServerSocket ss;
private void GUI(){
    // frame
    j = new JFrame("server");
    j.setBounds(10, 10, 500, 500);
    j.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    // text
    textdis = new JTextArea();
    textdis.setBounds(10, 10, 480, 300);
    textgui = new JTextField();
    textgui.setBounds(10, 320, 300, 30);
    entertextgui entergui = new entertextgui();
    textgui.addKeyListener(entergui);
    // button
    gui = new JButton("Gui");
    gui.setBounds(320, 320, 80, 30);
    guidi gd = new guidi();
    gui.addActionListener(gd);
            
    
    // container
    c= j.getContentPane();
    c.setLayout(null);
    c.add(textdis);
    c.add(textgui);
    c.add(gui);
    
    j.setVisible(true);
}
public server(){
    GUI(); // Giao dien
    KhoiTao();
    
}
private void KhoiTao(){
    
    try {
        ss = new ServerSocket(1234);
        System.out.println("Da tao server port 1234");
        s = ss.accept();
        
        System.out.println("Co client ket noi");
        os = s.getOutputStream();
        is = s.getInputStream();
        threadnhap = new inputstream();
        threadnhap.start();
    } catch (IOException ex) {
        System.out.println("Loi phan socket: " +ex.getMessage());
    }
}

// Hàm để gủi dữ liệu lên Stream
private void nutgui(){
    
    try{
        
        
        pw =new PrintWriter(os);
        String gui=textgui.getText();
        System.out.println("Gui: "+gui);
        textdis.setText(textdis.getText()+"Server(me): "+gui+"\n");
        textgui.setText("");
        pw.println(gui); pw.flush();
    } catch (NullPointerException e){
        System.out.println("Loi nhap xuat, do chua co client ket noi");
        JOptionPane.showMessageDialog(textdis, "Loi");
        
        try {
            Thread.sleep(2000);
        } catch (InterruptedException ex) {
            Logger.getLogger(server.class.getName()).log(Level.SEVERE, null, ex);
        }
        System.exit(0);
    }
}


// class key listenr của textgui dùng gõ phím enter để gủi.
class entertextgui implements KeyListener{
    @Override
    public void keyTyped(KeyEvent e) {
    }

    @Override
    public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_ENTER) {
            nutgui();
        }
    }
    @Override
    public void keyReleased(KeyEvent e) {
    }
}



class inputstream extends Thread{

    @Override
    public void run() {
        Scanner sc = new Scanner(is);
        String nhan ="";
        while(true){
            nhan = sc.nextLine();
            textdis.setText(textdis.getText()+"Client: "+nhan+"\n");
            System.out.println("\n---- Nhan: " + nhan);
        }
    }
    
}

class guidi implements ActionListener{

    @Override
    public void actionPerformed(ActionEvent e) {
       nutgui();
    }
    
}
public static void main(String[] args) {
    server b = new server();
}
}
3 Likes

Bạn nên cho thêm ảnh chụp màn hình nữa nhé , để dễ hình dung bạn viết gì hơn . Thứ hai bạn nên mô tả mô hình ứng dụng hoạt động (Ý tưởng ) thì sẽ dễ góp ý hơn là chỉ Show code ra.

2 Likes

chụp hình từng client và server hả bạn?

Thường thì những bài viết giới thiệu ứng dụng mình làm ra thì họ luôn có bố cụ rõ ràng
từ Mục đích , ứng dụng vào đâu , các thư viện cần thiết , và đặc biệt là cách cài đặt ( Triển khai ) và một số hình ảnh minh họa cho ứng dụng . Bạn thử lên Github xem là biết ngay ^^~

Bạn còn nên chỉ rõ những đoạn code quan trọng nhất ( ví dụ như đoạn kết nối giữa client và server , và đoạn truyền gửi thông tin chẳng hạn ) . Mình cũng làm Java lâu và cũng làm ứng dụng Chat rồi nên mình lướt qua là biết bạn làm như thế nào ngay , nhưng một số bạn mới làm chưa quen thì sẽ rất tò mò tìm hiểu thử và thậm chí một bạn dùng ngôn ngữ khác cũng sẽ rất hứng thú tìm hiểu , Nên mình nghĩ bạn nên có thêm thông tin cho bài viết sẽ tốt hơn rất nhiều vì quan trọng là cái chính bạn đã làm tốt rồi ^^~

3 Likes

Bạn ơi vậy mình làm vậy có đúng không, có nên chia ra 1 thread để luôn đọc dữ liệu từ client không?

1 Like
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?