Giúp đỡ về ứng dụng chat bằng socket

smilequangkk

Member
18/12/12
108
19
18
26
Mình có 1 ứng dụng chat bằng console. Vấn đề của mình là chạy nhiều clien và khi server gửi message thì chỉ có 1 clien nhận. Mọi người xem giúp mình
Code:
import java.io.*;
import java.net.*;

public class Server {

    public static void main(String[] args) {
        try {
            ServerSocket serverSocket = new ServerSocket(8888);
            System.out.println("Khởi chạy máy chủ thành công");
            while (true) {
                //Tạo Thread mới khi có 1 Client kết nối thành công
                new ThreadSocket(serverSocket.accept()).start();
                System.out.println("Có 1 kết nối đến");
            }
        } catch (IOException e) {
            System.out.println("Exception: " + e.getMessage());
        }
    }
}
Code:
import java.io.*;
import java.net.*;

public class Client {

    public static void main(String[] args) throws IOException {
        Socket ClientSocket = new Socket("localhost", 8888);
        System.out.println("Kết nối thành công!");
        //Tạo luồng nhận dữ liệu từ bàn phím
        DataInputStream inFromUser = new DataInputStream(System.in);
        //Tạo luồng nhận dữ liệu từ Server
        DataInputStream inFromServer = new DataInputStream(ClientSocket.getInputStream());
        //Tạo luồng gửi dữ liệu lên Server
        DataOutputStream outToServer = new DataOutputStream(ClientSocket.getOutputStream());
        while (true) {
            try {
                System.out.println("\nClient: ");
                //Nhập dữ liệu nhập từ bàn phím rồi gửi lên Server
                String ask = inFromUser.readLine();
                outToServer.writeBytes(ask + "\n");

                //Đọc dữ liệu Server gửi về rồi in ra
                String listen = inFromServer.readLine();
                System.out.println("\nServer: " + listen);
            } catch (UnknownHostException e) {
                System.err.println("Không tìm thấy máy chủ");
                System.exit(1);
            } catch (IOException e) {
                System.err.println("Không thể kết nối với máy chủ");
                System.exit(1);
            }
        }
    }
}
Code:
import java.io.*;
import java.net.*;

public class ThreadSocket extends Thread {

    Socket socket;

    public ThreadSocket(Socket pSocket) {
        this.socket = pSocket;
    }

    @Override
    public void run() {
        try {
            //Tạo luồng nhận dữ liệu từ bàn phím
            DataInputStream inFromServer = new DataInputStream(System.in);
            //Tạo luồng nhận dữ liệu từ Client
            DataInputStream inFromClient = new DataInputStream(socket.getInputStream());
            //Tạo luồng gửi dữ liệu về Client
            DataOutputStream outToClient = new DataOutputStream(socket.getOutputStream());
            while (true) {
                //Đọc dữ liệu từ Client gửi tới rồi in ra
                String listen = inFromClient.readLine();
                System.out.println("\nClient: " + listen);

                System.out.println("\nServer: ");
                //Nhập dữ liệu từ bàn phím rồi gửi về Client
                String ask = inFromServer.readLine();
                outToClient.writeBytes(ask + "\n");
            }
        } catch (IOException e) {
        }
    }
}
 

Joe

Thành viên VIP
21/1/13
2,962
1,307
113
Hi,
You complicate your C/S because you don't think or analyse how a chat works:
1. Client_A accesses the Server and starts its conversation with the server
2. Client_B connects to the Server and starts its conversation with the server
3. Client_C connects to the Server and starts its conversation with the server
4. etc.

NOW: The Server and ALL Clients use System.in to get their message. It works fine on the Client site because every Client is physically (and logically) separated. BUT on the Server site ALL spawned ThreadSockets share the same System,in and get a message. The question is "to which ThreadSocket this message belong"? Because of uncertainty the JVM works chronologically Client_A, Client_B, Client_C, etc. OR: which Client starts firstly to listen and the next and the next...regardless of the correctness. Is that clear enough for you?

That's the reason why you get a real messy hodgepodge:))
 

Joe

Thành viên VIP
21/1/13
2,962
1,307
113
1. make the ThreadSocket independent from System.in using other input technique: Swing or JOptionPane
PHP:
import javax.swing.JOptionPane;

public class ThreadSocket extends Thread {

    Socket socket;

    public ThreadSocket(Socket pSocket) {
        this.socket = pSocket;
    }

    @Override
    public void run() {
        try {
            DataInputStream inFromClient = new DataInputStream(socket.getInputStream());
            DataOutputStream outToClient = new DataOutputStream(socket.getOutputStream());
            while (true) {
                String listen = inFromClient.readLine();
                if (listen == null) break;
                System.out.println("\nClient: " + listen);

                // individualize the conversation
                String ask = JOptionPane.showInputDialog("ThreadNo."+getId()+" to Client:");
                if (ask == null) break;
                outToClient.writeBytes("ThreadNo."+getId()+":"+ask + "\n");
            }
            inFromClient.close();
            outToClient.close();
            socket.close();
        } catch (IOException e) {
        }
    }
}[php]
Optional for the Client 
[php]
import java.io.*;
import java.net.*;

import javax.swing.JOptionPane;

public class Client {

    public static void main(String[] args) throws IOException {
        Socket ClientSocket = new Socket("localhost", 8888);
        System.out.println("success!");
        DataInputStream inFromServer = new DataInputStream(ClientSocket.getInputStream());
        DataOutputStream outToServer = new DataOutputStream(ClientSocket.getOutputStream());
        while (true) {
            try {
                // individualize the conversation
                String ask = JOptionPane.showInputDialog("To Server:");
                if (ask == null) break;
                outToServer.writeBytes(ask + "\n");

                String listen = inFromServer.readLine();
                if (listen == null) break;
                System.out.println("\nServer: " + listen);
            } catch (UnknownHostException e) {
                System.exit(1);
            } catch (IOException e) {
                System.exit(1);
            }
        }
        inFromServer.close();
        outToServer.close();
        ClientSocket.close();
    }
}{php]
 

Attachments

Joe

Thành viên VIP
21/1/13
2,962
1,307
113
1. make the ThreadSocket independent from System.in using other input technique: Swing or JOptionPane
PHP:
import javax.swing.JOptionPane;

public class ThreadSocket extends Thread {

    Socket socket;

    public ThreadSocket(Socket pSocket) {
        this.socket = pSocket;
    }

    @Override
    public void run() {
        try {
            DataInputStream inFromClient = new DataInputStream(socket.getInputStream());
            DataOutputStream outToClient = new DataOutputStream(socket.getOutputStream());
            while (true) {
                String listen = inFromClient.readLine();
                if (listen == null) break;
                System.out.println("\nClient: " + listen);

                // individualize the conversation
                String ask = JOptionPane.showInputDialog("ThreadNo."+getId()+" to Client:");
                if (ask == null) break;
                outToClient.writeBytes("ThreadNo."+getId()+":"+ask + "\n");
            }
            inFromClient.close();
            outToClient.close();
            socket.close();
        } catch (IOException e) {
        }
    }
}[php]
Optional for the Client 
[php]
import java.io.*;
import java.net.*;

import javax.swing.JOptionPane;

public class Client {

    public static void main(String[] args) throws IOException {
        Socket ClientSocket = new Socket("localhost", 8888);
        System.out.println("success!");
        DataInputStream inFromServer = new DataInputStream(ClientSocket.getInputStream());
        DataOutputStream outToServer = new DataOutputStream(ClientSocket.getOutputStream());
        while (true) {
            try {
                // individualize the conversation
                String ask = JOptionPane.showInputDialog("To Server:");
                if (ask == null) break;
                outToServer.writeBytes(ask + "\n");

                String listen = inFromServer.readLine();
                if (listen == null) break;
                System.out.println("\nServer: " + listen);
            } catch (UnknownHostException e) {
                System.exit(1);
            } catch (IOException e) {
                System.exit(1);
            }
        }
        inFromServer.close();
        outToServer.close();
        ClientSocket.close();
    }
}{php]
 

Joe

Thành viên VIP
21/1/13
2,962
1,307
113
Make your ThreadSocket independent from System.in as following (just an example)
PHP:
import java.io.*;
import java.net.*;
//
import javax.swing.JOptionPane;

public class ThreadSocket extends Thread {

    Socket socket;

    public ThreadSocket(Socket pSocket) {
        this.socket = pSocket;
    }

    @Override
    public void run() {
        try {
            DataInputStream inFromClient = new DataInputStream(socket.getInputStream());
            DataOutputStream outToClient = new DataOutputStream(socket.getOutputStream());
            while (true) {
                String listen = inFromClient.readLine();
                if (listen == null) break;
                System.out.println("\nClient: " + listen);

                // individualize the conversation
                String ask = JOptionPane.showInputDialog("ThreadNo."+getId()+" to Client:");
                if (ask == null) break;
                outToClient.writeBytes("ThreadNo."+getId()+":"+ask + "\n");
            }
            inFromClient.close();
            outToClient.close();
            socket.close();
        } catch (IOException e) {
        }
    }
}
Optional for the Client
PHP:
import java.io.*;
import java.net.*;

import javax.swing.JOptionPane;

public class Client {

    public static void main(String[] args) throws IOException {
        Socket ClientSocket = new Socket("localhost", 8888);
        System.out.println("success!");
        DataInputStream inFromServer = new DataInputStream(ClientSocket.getInputStream());
        DataOutputStream outToServer = new DataOutputStream(ClientSocket.getOutputStream());
        while (true) {
            try {
                // individualize the conversation
                String ask = JOptionPane.showInputDialog("To Server:");
                if (ask == null) break;
                outToServer.writeBytes(ask + "\n");

                String listen = inFromServer.readLine();
                if (listen == null) break;
                System.out.println("\nServer: " + listen);
            } catch (UnknownHostException e) {
                System.exit(1);
            } catch (IOException e) {
                System.exit(1);
            }
        }
        inFromServer.close();
        outToServer.close();
        ClientSocket.close();
    }
}
see picture
 

Attachments