在Java内利用Socket实现在控制台进行实时聊天

版权声明:转载请注明出处与链接。 https://blog.csdn.net/With_Her/article/details/80108580

本Demo是在CSDN的其他一篇关于Socket通信的Demo基础上,利用多线程实现了服务端与客户端的相互通信。

原Demo博客的地址https://blog.csdn.net/qiuyoungster/article/details/58030191

第一次在CSDN发博客,还有很多不懂的地方,望大佬们多多指点。

package com.lvjia.car.socket;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

public class Server {
    private ServerSocket serverSocket;
    private final Map socketMap=new HashMap();
    private final Map clientSizeMap=new HashMap();


    public Server(){
        try{
            serverSocket = new ServerSocket(8088);
        }catch(Exception e){
            e.printStackTrace();
        }
    }

    public void start(){


        try{
            Socket socket = null;

            new Thread(new Runnable() {//创建一条线程,向客户端发送消息
                @Override
                public void run() {
                    Scanner scanner = new Scanner(System.in);
                    while(true){
                        String demo=scanner.nextLine();
                        String[] demoArray=demo.split("/:");
                        String socketIp=demoArray[0];
                        String info=demoArray[1];

                        System.out.println("服务端输入的ip"+socketIp);
                        System.out.println("服务端发送的消息:"+info);
                        Socket socket=(Socket)socketMap.get(socketIp);
                        try{
                            OutputStream out = socket.getOutputStream();
                            //OutputStreamWriter osw = new OutputStreamWriter(out, true);
                            OutputStreamWriter osw = new OutputStreamWriter(out, "UTF-8");
                            PrintWriter pw = new PrintWriter(osw, true);
                            pw.println("你好!客户端!");
                            //创建Scanner读取用户输入内容

                                //scan.nextLine();
                                pw.println(info);

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

                }
            }).start();

            //serverSocket.accept() 方法会产生阻塞,直到某个Socket连接,返回请求连接的Socket
            while ((socket = serverSocket.accept())!=null){//每当有新的客户端连接到服务器,便创建一条线程,获取连接到服务端的客户端,并将之socket保存在Map集合中
                final  Socket socket1 = socket;
                socketMap.put(socket1.getInetAddress().getHostAddress(),socket1);
                System.out.println("===========================================");
                System.out.println("有新的连接,新连接的客户端Ip"+socket1.getInetAddress().getHostAddress());
                System.out.println("当前连接的客户端总数:"+socketMap.size()+"");
                Integer clientsize=socketMap.size();
                clientSizeMap.put(socket1.getInetAddress().getHostAddress(),clientsize);

                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        System.out.println("客户端"+clientsize+"已连接!");
                        System.out.println("===========================================");
                        try {
                            Integer number =(Integer) clientSizeMap.get(socket1.getInetAddress().getHostAddress());
                            InputStream in = socket1.getInputStream();
                            InputStreamReader isr = new InputStreamReader(in, "UTF-8");
                            BufferedReader br = new BufferedReader(isr);
                            //不断读取客户端数据
                            while(true){
                                System.out.println("客户端"+number+"说:" + br.readLine());
                            }
                        }catch (Exception e){
                        }

                    }
                }).start();
            }


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

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Server server = new Server();
        server.start();
    }
}
package com.lvjia.car.socket;

import java.io.*;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

public class Client {
    private  Socket socket;

    public Client(){
        try {
            socket = new Socket("localhost", 8088);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void start(){
        final  Socket socket1=this.socket;
        new Thread(new Runnable() {//创建一条线程,监听获取服务端发送的消息
            @Override
            public void run() {
                try {
                    InputStream in = socket1.getInputStream();
                    InputStreamReader isr = new InputStreamReader(in, "UTF-8");
                    BufferedReader br = new BufferedReader(isr);
                    //System.out.println("客户端说:" + br.readLine());
                    //不断读取客户端数据
                    while(true){
                        System.out.println("服务端说:" + br.readLine());
                    }
                }catch (Exception e){
                }
            }
        }).start();

        try{//向服务端发送消息
            OutputStream out = socket.getOutputStream();
            //OutputStreamWriter osw = new OutputStreamWriter(out, true);
            OutputStreamWriter osw = new OutputStreamWriter(out, "UTF-8");
            PrintWriter pw = new PrintWriter(osw, true);
            pw.println("你好!服务器!");
            //创建Scanner读取用户输入内容
            Scanner scanner = new Scanner(System.in);
            while(true){
                //scan.nextLine();
                System.out.println("尊敬的用户,请您输入:");
                pw.println(scanner.nextLine());
            }
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            if(socket != null){
                try{
                    socket.close();
                }catch(Exception e){
                    e.printStackTrace();
                }
            }
        }

    }

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Client client = new Client();
        client.start();
    }
}
 
 

分为服务器端和客户端

注意:在启动时,先启动Server,再启动Client

不然会报    java.net.ConnectException: Connection refused: connect    异常.

==========================


启动后,Server控制台:


Client控制台:


==========================

在客户端,客户端向服务端发送消息时,直接输入想要发送的消息,然后回车,就ok

在服务端,服务端想某个客户端发送消息时,格式为:该客户端IP+/:Hello CSDN。例如:127.0.0.1/:Hello CSDN



第一次发稿,有很多不足,希望可以相互交流学习。

猜你喜欢

转载自blog.csdn.net/With_Her/article/details/80108580