Socket简单实现多线程通信

闲来无事,把之前用到的整理上来以备忘

SocketServer 类实现:


import java.io.*;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;

public class SocketServer extends Thread {

    String tag = "服务器:";
    String ip;
    int port = 0;
    ServerSocket serverSocket;
    int countClient = 0;
    private ArrayList sockets = new ArrayList<>();

    public static SocketServer getInstance(){
        return SingleInstance.INSTANCE;
    }

    public static class SingleInstance{
        private final static SocketServer INSTANCE = new SocketServer();
    }

    public SocketServer bindPort(int port){
        this.port = port;
        return this;
    }

    @Override
    public void run() {
        super.run();
        Socket socket = null;
        while (true){
            try {
                if(null==serverSocket||serverSocket.isClosed()){
                    System.out.println(tag+"开始绑定端口");
                    serverSocket = new ServerSocket(port);
                }
                System.out.println(tag+"等待客户端接入");
                socket = serverSocket.accept();
                ClientThread clientThread = new ClientThread(socket);
                clientThread.start();
                countClient++;
                sockets.add(socket);
                InetAddress inetAddress = socket.getInetAddress();
                System.out.println(tag+"客户端数量:"+countClient+",当前连入客户端是:"+inetAddress.getHostAddress());
            }catch (IOException e){
                System.out.println(tag+"Server error:"+e.getCause());
            }

        }
    }

    public void publishOthers(Socket socket,String data){
        for(Socket item:sockets){
            if(item!=socket&&!item.isClosed()){
                try {
                    System.out.println(tag+socket+"将数据"+data+"广播给"+item);
                    OutputStream outputStream = item.getOutputStream();
                    PrintWriter pw = new PrintWriter(outputStream);
                    pw.write(data);
                    pw.flush();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
        }
    }

    public class ClientThread extends Thread{
        Socket socket ;
        public ClientThread(Socket socket){
            this.socket = socket;
        }

        @Override
        public void run() {
            super.run();
            InputStream inputStream = null;
            OutputStream outputStream = null;
            InputStreamReader inputStreamReader = null;
            BufferedReader bufferedReader = null;
            String input = null;
            while (true){
                try {
                    System.out.println(tag+"ClientThread.run");
                    inputStream = socket.getInputStream();
                    inputStreamReader = new InputStreamReader(inputStream);
                    bufferedReader = new BufferedReader(inputStreamReader);
                    while ((input=bufferedReader.readLine())!=null){
                        System.out.println(tag+"data from client="+input);
                        publishOthers(socket,input);
                    }
                }catch (IOException e){
                    System.out.println(tag+"ClientThread error e:"+e.getCause());
                    try {
                        if(null!=inputStream)
                            inputStream.close();
                        if(null!=outputStream){
                            outputStream.close();
                        }
                        if(null!=inputStreamReader){
                            inputStreamReader = null;
                        }
                        if(null!=bufferedReader)
                            bufferedReader.close();
                        if(null!=socket)
                            socket.close();
                    }catch (IOException e1){
                        System.out.println(tag+"ClientThread error e1:"+e1.getCause());
                    }
                }
            }

        }
    }
}

 

接下来 SocketClient类实现


import java.io.*;
import java.net.Socket;

public class SocketClient extends Thread {
    String tag = "客户端"+toString();
    String address;
    int port = 0;
    Socket socket;
    String sendMsg;
    public static SocketClient getInstance(){
        return SingleInstance.INSTANCE;
    }
    public static class SingleInstance {
        private final static SocketClient INSTANCE = new SocketClient();
    }

    public SocketClient bindServer(String address,int port){
        if(null==address||address.length()==0||port<0){
            System.out.println(tag+"SocketClient 地址或者端口不正确");
        }
        this.address = address;
        this.port = port;
        return this;
    }

    OutputStream outputStream = null;
    InputStream inputStream = null;
    BufferedReader bufferedReader = null;
    @Override
    public void run() {
        super.run();
        while (true){
            try {
                if(null==socket||socket.isClosed()){
                    System.out.println(tag+"Socket Connect to "+address+" : "+port);
                    socket = new Socket(address,port);
                    outputStream = socket.getOutputStream();
                    inputStream = socket.getInputStream();
                    bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
                }
                String data = null;
                while ((data=bufferedReader.readLine())!=null){
                    System.out.println(tag+"get data from server:"+data);
                }

            }catch (IOException e){
                System.out.println(tag+"error:"+e.getCause());
            }

        }
    }

    public void sendMsg(String data){
        if(sendMsgThread==null){
            sendMsgThread = new SendMsgThread();
            sendMsgThread.start();
        }
        this.sendMsg = data;
        synchronized (sendMsgThread){
            sendMsgThread.notify();
        }
    }

    private SendMsgThread sendMsgThread;
    public class SendMsgThread extends Thread{

        @Override
        public void run() {
            super.run();
            while (true){
                synchronized (this){
                    if(null==sendMsg||sendMsg.length()==0){
                        try {
                            System.out.println(tag+"SendMsgThread wait-------------");
                            wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }else{
                        System.out.println(tag+"SendMsgThread notify-----------------");
                        notify();
                    }
                    if(null!=outputStream){
                        System.out.println(tag+"SendMsgThread write");
                        PrintWriter pw = new PrintWriter(outputStream);
                        pw.write(sendMsg);
                        pw.flush();
                        sendMsg = null;
                    }
                }

            }
        }
    }
}
 

简单测试程序

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

public class Main {

    public static void main(String[] args) {
        ArrayList clients = new ArrayList<>();
        System.out.println("Start Main :: Socket Server Start...");
        SocketServer.getInstance().bindPort(7777).start();

        try {
            Thread.sleep(3000);
            System.out.println("Start Main :: after 3000...");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        SocketClient socketClient1 = new SocketClient().bindServer("127.0.0.1",7777);
        System.out.println("Start Main :: SocketClient start:"+socketClient1);
        socketClient1.start();

        try {
            Thread.sleep(2000);
            System.out.println("Start Main :: after 3000...");
            SocketClient socketClient2 = new SocketClient().bindServer("127.0.0.1",7777);
            System.out.println("Start Main :: SocketClient start:"+socketClient2);
            socketClient2.start();

            Thread.sleep(2000);
            System.out.println("Start Main :: after 3000...");
            socketClient1.sendMsg("你好,我是"+socketClient1+"\r\n");
            Thread.sleep(2000);
            System.out.println("Start Main :: after 3000...");
            socketClient1.sendMsg("你好,我是"+socketClient1+"\r\n");

            Thread.sleep(2000);
            System.out.println("Start Main :: after 3000...");
            socketClient2.sendMsg("你好,我是2"+socketClient2+"\r\n");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }


    }
}

 

测试结果:

D:\java\jdk1.8.0_181\bin\java.exe "-javaagent:D:\JetBrains\IntelliJ IDEA 2018.2.3\lib\idea_rt.jar=50325:D:\JetBrains\IntelliJ IDEA 2018.2.3\bin" -Dfile.encoding=UTF-8 -classpath D:\java\jdk1.8.0_181\jre\lib\charsets.jar;D:\java\jdk1.8.0_181\jre\lib\deploy.jar;D:\java\jdk1.8.0_181\jre\lib\ext\access-bridge-64.jar;D:\java\jdk1.8.0_181\jre\lib\ext\cldrdata.jar;D:\java\jdk1.8.0_181\jre\lib\ext\dnsns.jar;D:\java\jdk1.8.0_181\jre\lib\ext\jaccess.jar;D:\java\jdk1.8.0_181\jre\lib\ext\jfxrt.jar;D:\java\jdk1.8.0_181\jre\lib\ext\localedata.jar;D:\java\jdk1.8.0_181\jre\lib\ext\nashorn.jar;D:\java\jdk1.8.0_181\jre\lib\ext\sunec.jar;D:\java\jdk1.8.0_181\jre\lib\ext\sunjce_provider.jar;D:\java\jdk1.8.0_181\jre\lib\ext\sunmscapi.jar;D:\java\jdk1.8.0_181\jre\lib\ext\sunpkcs11.jar;D:\java\jdk1.8.0_181\jre\lib\ext\zipfs.jar;D:\java\jdk1.8.0_181\jre\lib\javaws.jar;D:\java\jdk1.8.0_181\jre\lib\jce.jar;D:\java\jdk1.8.0_181\jre\lib\jfr.jar;D:\java\jdk1.8.0_181\jre\lib\jfxswt.jar;D:\java\jdk1.8.0_181\jre\lib\jsse.jar;D:\java\jdk1.8.0_181\jre\lib\management-agent.jar;D:\java\jdk1.8.0_181\jre\lib\plugin.jar;D:\java\jdk1.8.0_181\jre\lib\resources.jar;D:\java\jdk1.8.0_181\jre\lib\rt.jar;E:\IdeaProjects\untitled\out\production\untitled Main
Start Main :: Socket Server Start...
服务器:开始绑定端口
服务器:等待客户端接入
Start Main :: after 3000...
Start Main :: SocketClient start:Thread[Thread-1,5,main]
客户端Thread[Thread-1,5,main]Socket Connect to 127.0.0.1 : 7777
服务器:客户端数量:1,当前连入客户端是:127.0.0.1
服务器:等待客户端接入
服务器:ClientThread.run
Start Main :: after 3000...
Start Main :: SocketClient start:Thread[Thread-3,5,main]
客户端Thread[Thread-3,5,main]Socket Connect to 127.0.0.1 : 7777
服务器:客户端数量:2,当前连入客户端是:127.0.0.1
服务器:等待客户端接入
服务器:ClientThread.run
Start Main :: after 3000...
客户端Thread[Thread-1,5,main]SendMsgThread notify-----------------
客户端Thread[Thread-1,5,main]SendMsgThread write
客户端Thread[Thread-1,5,main]SendMsgThread wait-------------
服务器:data from client=你好,我是Thread[Thread-1,5,main]
服务器:Socket[addr=/127.0.0.1,port=50330,localport=7777]将数据你好,我是Thread[Thread-1,5,main]广播给Socket[addr=/127.0.0.1,port=50331,localport=7777]
Start Main :: after 3000...
客户端Thread[Thread-1,5,main]SendMsgThread write
客户端Thread[Thread-1,5,main]SendMsgThread wait-------------
服务器:data from client=你好,我是Thread[Thread-1,5,main]
服务器:Socket[addr=/127.0.0.1,port=50330,localport=7777]将数据你好,我是Thread[Thread-1,5,main]广播给Socket[addr=/127.0.0.1,port=50331,localport=7777]
Start Main :: after 3000...
客户端Thread[Thread-3,5,main]SendMsgThread notify-----------------
客户端Thread[Thread-3,5,main]SendMsgThread write
客户端Thread[Thread-3,5,main]SendMsgThread wait-------------
服务器:data from client=你好,我是2Thread[Thread-3,5,main]
服务器:Socket[addr=/127.0.0.1,port=50331,localport=7777]将数据你好,我是2Thread[Thread-3,5,main]广播给Socket[addr=/127.0.0.1,port=50330,localport=7777]
 

未尽完善,还请路过大神不吝赐教。

 

你可能感兴趣的:(JAVA学习)