使用TCP协议和多线程实现实时聊天室

先来说说实现实时聊天室的思路:
现假设只有两个人聊天,即客户端1、客户端2和服务器。
客户端1向客户端2发送一条消息,实质上是客户端1先向服务器发送消息,然后服务器通过检测它要发送的地址,然后将消息再发送给客户端2;同样客户端2向客户端1发送消息流程也是这样。那么,如果是多人聊天,服务器只要不发送给向它发送消息的客户端,其他客户端全部发送就可以了。现在,开始详细讲解代码的实现过程:

服务器端的功能:接收客户端发送过来的消息,然后向其余客户端发送消息,大家都知道,客户端与服务器的连接都是通过socket套接字完成的,所以我们需要创建一个集合,用来存储已与服务器连接的套接字。由于每个套接字代表了一段通信,所以我们需要使用线程来实现接收和发送消息的过程。

客户端的功能:向服务器发送消息,接收服务器发送过来的其他客户端的消息。我们需要给发送和接收分别套一个线程,原因如下:在聊天过程中,我们可能会向对方连续发送消息,在这种情况下,如果我们不使用线程,就会导致我们只能等待对方向我们发送消息后才能再次向对方发送消息;而使用了多线程,就可以完全避免这个问题。

实时聊天的实现:这个很简单,只需要写一个死循环就可以实现该功能。

具体实现如下:
客户端:

package com.zhaoxin.tcpchat;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;

public class Client {
    public static void main(String[] args) {

        try {
            Socket socket = new Socket("192.168.0.138", 8888);
            // 接收服务器端响应的消息
            new Thread() {
                @Override
                public void run() {
                    try {
                        InputStream is = socket.getInputStream();
                        byte[] data = new byte[1024];
                        int length = -1;
                        while ((length = is.read(data)) != -1) {
                            System.out.println(new String(data, 0, length));
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }.start();

            // 向服务器发送消息
            new Thread() {
                @Override
                public void run() {
                    try {
                        Scanner reader = new Scanner(System.in);
                        while (true) {
                            String info = reader.next();
                            OutputStream os = socket.getOutputStream();
                            os.write(info.getBytes());
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }.start();

        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

服务器:

package com.zhaoxin.tcpchat;

import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;

public class Server {



    // 创建一个集合,用来装已连接客户端的套接字
    private static ArrayList list = new ArrayList();

    public static void main(String[] args) {
        Server server = new Server();
        try {
            ServerSocket serverSocket = new ServerSocket(8888);
            while (true) {
                Socket socket = serverSocket.accept();
                ChatThread thread = server.new ChatThread(socket);
                list.add(socket);
                thread.start();
            }

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

    class ChatThread extends Thread {

        private Socket socket = null;
        private byte[] data;

        public ChatThread(Socket socket) {
            this.socket = socket;
        }

        @Override
        public void run() {

            try {

                // 从客户端接收消息
                InputStream is = socket.getInputStream();
                data = new byte[1024];
                int length = -1;
                while ((length = is.read(data)) != -1) {
                    System.out.println(new String(data, 0, length));
                    data = ("对方说:" + new String(data, 0, length)).getBytes();

                    // 向其他客户端响应消息
                    for (int i = 0; i < list.size(); i++) {
                        if (list.get(i) != socket) {
                            list.get(i).getOutputStream().write(data);
                        }
                    }

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

    }

}

你可能感兴趣的:(java)